Vu-Meter stereo shield


Introduzione

Il mio recente interesse verso la gestione di temperature, attraverso l’utilizzo di PIC, mi ha portato a scoprire il fantastico mondo dei segnali analogici che, opportunamente trattati, forniscono interessanti informazioni al microcontrollore che sarà in grado di sviluppare conseguenti azioni.

Nel mio progetto “Temperatura 1a parte”, accessibile dal seguente link

Temperatura interna e esterna su LCD 2x16 per Micro-GT mini

avevo avuto modo di testare, prendendone confidenza, la Micro-GT versatile IDE con un PIC16F877A della Microchip, mi sono molto divertito, avendo anche la possibilità di testare a fondo tale scheda con a bordo tutto quanto indispensabile per la programmazione e la realizzazione di innumerevoli test. Nel frattempo ho preso confidenza con i Display LCD, dispositivo di output per me molto gradevole ed interessante (oltre che abbastanza economico).

Dicono che da cosa nasce cosa e siccome l’appetito viene mangiando, dopo ogni esperienza nasce la voglia di rispolverare, grazie alle conoscenze acquisite con nuove sperimentazioni, dei vecchi progetti che sono rimasti irrealizzati per qualche motivo, pertanto ho rivisto una vecchia idea, concepita inizialmente con output su LED, pensata e realizzata da un conoscente, che però non era di mio gradimento considerato il pannello nel quale avrei dovuto applicare il dispositivo di output.

Adesso potendo gestire con facilità un Display LCD pilotato da un PIC, tramite un semplice e piccolo shield, di mia implementazione, denominato “Vu-Meter stereo shield”, realizzato principalmente con componenti recuperati o disponibili nel mio laboratorio hobbistico, ho voluto realizzare un sistema che, leggendo i segnali degli altoparlanti di uno stereo, potesse visualizzare su un Display LCD delle barre, formate da caratteri di testo, indicanti il volume d’uscita dei due canali.

Problema: mi butto subito a realizzare il progetto o prima realizzo, step by step, quanto necessario, testando man mano ogni cosa ed a risposte positive ottenute dedicarmi poi all’esecuzione finale?

Nel mio modo di concepire le cose ho sempre preferito la seconda soluzione e quindi, dopo aver realizzato il piccolo “Vu-Meter stereo shield” (eseguito per ragioni d’urgenza e provvisorietà con FidoCad), ho subito cominciato a scrivere il codice sorgente relativo da trasferire nel microcontrollore. Purtroppo, ragioni di spazio dovuti ad un trasferimento del mio tavolo di lavoro ad altra stanza nonché alla caotica situazione venutasi a creare, sono stato limitato nell’utilizzo della Micro-GT versatile IDE che egregiamente ho sempre usato per tutte le altre applicazioni.

 

 
 

Realizzazioni grafiche (serigrafia e stampa lato rame per PCB) create con FidoCad

PCB realizzato con pellicola Photosensitive dry film - negative photoresist - DuPont

Soluzione? Frequentando un negozio di elettronica di Rovigo, ho potuto acquistare una scheda denominata Micro GT mini (con un PIC16F876A della Microchip) ovvero la sorella più piccola della versatile IDE (che già possedevo e che conoscevo molto bene) che offre le stesse possibilità di programmazione e che, essendo totalmente FREE PORT, propone anche le stesse altre potenzialità tramite dispositivi collegati esternamente.

Micro GT mini corredata di PIC16F876A della Microchip

Il costo limitato e quanto potenzialmente può offrire, mi ha particolarmente allettato e, pertanto mi sono messo immediatamente all’opera.

Tutto quanto realizzato fino a questo momento fa parte della prima fase del mio progetto che mi consente, con quanto già attuato, di verificare efficacemente il reale funzionamento dell’insieme.

La realizzazione finale del progetto definitivo sarà affrontata successivamente ed eventualmente farà parte di un secondo articolo da pubblicare.

 

Parti del sistema

Il sistema si compone di una parte logica programmabile costituita dalla suddetta piattaforma Micro-GT mini che, come sappiamo monta per default il microcontrollore 16F876A, ma potrebbe alloggiare anche alcune versioni compatibili a 28 pin della serie 18.

Necessariamente si deve elaborare il segnale musicale prelevato dalla fonte audio eseguendo il taglio della semionda negativa, in modo da non mettere in crisi i convertitori AD del PIC che ne potrebbero risultare addirittura danneggiati. Si preferisce anche eseguire la compressione logaritmica del segnale in maniera hardware semplificando di conseguenza il firmware. Tale elaborazione è svolta dall'interfaccia Vu-Meter stereo shield”,


 

Ultimo, ma non meno importante è il Display LCD 2 x 16, (ecco un disegno da me realizzato in Corel Draw e poi esportato in JPG, che mi aiuta molto quando mi serve consultare il pinout del Display LCD).

 

Guadagno dell’amplificatore

Studio del guadagno dell’amplificatore logaritmico con retroazione negativa, configurazione non invertente:

Analisi dello schema

Nello schema sotto riportato il guadagno della retroazione negativa in configurazione:

Non invertente vale: 

Vo=(1+(Rf/Ri))*Vi se Vi arriva a 200 mV (la musica vale 200mV=0,2V)

Vomax=5V

Prima Condizione:

Vo=5V Vi=0,2V Ri=10k

5V=(1+(Rf/Ri))*Vi ==> 25-1=(Rf/Ri) ==> 24=(Rf/Ri) ==> Rf=240k e Ri=10k

Seconda Condizione:

Vo=2V Vi=0,2V Ri=10k

2V=(1+(Rf/Ri))*Vi ==> 9=(Rf/Ri) ==> Rf=90k

Terza Condizione:

Vo? Vi=0,2V Rf=50k Ri=10k

Vo=(1+(Rf/Ri))*Vi ==> Vo=[(10+50)/10]*0,2V ==> V0=1,2V

Quarta Condizione:

Vo=0,5V Vi=0,2V Ri=10k 

 

0,5V=(1+(Rf/Ri))*Vi ==> 1,5=(Rf/Ri) ==> Rf=0,00015 Ohm 

Schema in formato EAGLE scaricabile da questo link

Elenco Componenti:

Sezione Interfaccia shield Vu-Meter

Sezione logica (minimale)

Nella foto seguente, che ritrae la Micro-GT mini, vediamo dove collegare i pin 1 e 2, all’interno del cerchio rosa che indica i canali analogici AN0 e AN1 (AN0 a destra nella foto), inoltre, nell’immagine sono state indicate anche la posizione del PORT C (in arancione) e del PORB (in rosso) (i rispettivi pin n° 1 iniziano a sinistra relativamente alla foto):

 

I canali AN0 e AN1 sono evidenziati in rosa nel seguente pinout del PIC16F876A (analogo al PIC16F873) a bordo della Micro-GT mini:

 

 

 Il firmware

Prima di dedicarci al codice del firmware, c’è da prendere confidenza con l’acquisizione di segnali analogici, per l’argomento non voglio ripetermi e potete ricavare le opportune informazioni sempre nel mio progetto “Temperatura 1a parte”, di cui al link che riporto nuovamente di seguito:

Temperatura interna e esterna su LCD 2x16 per Micro-GT mini

A seguire il file principale:

 File sorgente V-Meter.c

/*********************************************************
*                                                                                          *
*                            Autore - Giuseppe Bonfiglio               *
*  Visualizza su LCD 2 x 16 il valore, in                          *
*  tensione, rilevato in due canali analogici del              *
*  modulo Hardware V-Meter stereo shield                    *
*                                                                                           *
*                                      28-01-2014                                 *
*                                                                                            *
*  Progetto: V-Meter                                                           *
*  Piattaforma: - Micro-GT mini                                          *
*  MPLAB -  X Vers. 1.81                                                    *
*  Compilatore:  HI-TECH PICC (v. 9.81)                          *
*  MCU - PIC 16F876A                                                         *
*  Sorgente - V-Meter.c                                                         *
*                                                                                                *
**************************************************************/
 

#define _LEGACY_HEADERS  // permette di acquisire la sintassi dei compilatori precedenti

 

#include<pic.h>

#include<stdio.h>

#include<stdlib.h>

#include<math.h>

#include"Delay.h"

#include"ADC.h"

 

#define EN RC2                                  //SV 24 pin 3 nella Micro GT IDE

#define RW RC1                                 //SV 24 pin 2 nella Micro GT IDE

#define RS RC0                                  //SV 24 pin 1 nella Micro GT IDE

 

#define FR_0 "              "              //Frase per valore 0

#define FR_1 "#             "              //Frase per valore 1

#define FR_2 "##            "              //Frase per valore 2

#define FR_3 "###           "              //Frase per valore 3

#define FR_4 "####          "              //Frase per valore 4

#define FR_5 "#####         "              //Frase per valore 5

#define FR_6 "######        "              //Frase per valore 6

#define FR_7 "#######       "              //Frase per valore 7

#define FR_8 "########      "              //Frase per valore 8

#define FR_9 "#########     "              //Frase per valore 9

#define FR_10 "##########    "              //Frase per valore 10

#define FR_11 "##########*   "              //Frase per valore 11

#define FR_12 "##########**  "              //Frase per valore 12

#define FR_13 "##########**> "              //Frase per valore 13

#define FR_14 "##########**>>"              //Frase per valore 14

 

// #define XTAL_FREQ 20MHZ  //calibtare frequency oscillator

 

__CONFIG (HS & WDTEN & PWRTDIS & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT); //Fuses

 

void CLOCK();

void CLEAR();

void CONFIGURA();

void INIZIALIZZA();

void splash();

void VAI(unsigned char r, unsigned char c);

void SCRIVI(char lettera);

void FRASE(unsigned char l, unsigned char n, const char* msg1);

void scrivi_barra(int canale, int riga);

 

#include"configurazioni.h"

#include"LCD_2x16-28-PIN.h"

#include"splash.h"

#include"Leggi_Canali_R_L .h"

 /*-----------------------------------------------------------------------------*/

 

void main(){

                        CONFIGURA();

                        INIZIALIZZA();

                        CLEAR();

                        DelayMs(10);

                        splash();

 

while(1){

 

                scrivi_barra(0, 1);

                scrivi_barra(1, 2);

                // DelayMs(1);

 

                CLRWDT();

                        }

}

 

Principali librerie

File libreria ACD.h

 

/******************************************************************
*                                                                                                        *
* MODULO PER LA LETTURA DEI CANALI ANALOGICI     *
*                                                                                                        *
*          chiamare la fz leggi_ad(n);                                                *
*   dove n: è il numero del canale in ingresso                             *
*                                                                                                        *
*                                                                                                        *
******************************************************************/

 

int leggi_ad(char canale)

{

            int valore;

 

            ADCON0 = (canale << 3) + 0xC1;   // enable ADC, RC osc + 193 ovvero il 193 setta il clock .

 

            DelayUs(10);                          //Ritardo per dare modo all'A/D di stabilizzarsi 10 Us

       

            ADGO = 1;                                        //Fa partire la conversione

 

            while(ADGO)

                                   continue;         //Attende che la conversione sia completa

       

        valore = ADRESL;                    //Parte bassa del risultato

         valore = valore + (ADRESH<<8);  //Parte alta del risultato

           

            return(valore);

}

 

File libreria configurazioni.h

/******************************************************************
 *                                                                                                       *
 *         File:   configurazioni.h                                                         *
 *                                                                                                        *
 *                MCU 16F876A                                                              *
 *                Piattaforma Micro-GT IDE / mini                                 *
 *                                                                                                        *
 *       Modulo: configurazioni -> Configura l' I/O                           *
 *                         delle Porte e la gestione                                       *
 *                         dei canali analogici                                               *
 *                                                                                                         *
 *  Autore Ing. Marco Gottardo                                                        *
 *  Libreria modificata da Giuseppe Bonfiglio il 28-01-2014           *
 *                                                                                                         *
 *  Attenzione: non superare l'area di stampa                                *
 * ******************************************************************/
 

void CONFIGURA(){

                TRISA=0xFF;              // 11111111

                TRISB=0b00000000;

                TRISC=0b11110000;        // primo nibble ingressi, lascio libera la seriale

                PORTB=0;

                PORTC=0;

                OPTION=0x80;             //10000000

                ADCON1=0b10000100;

}

 

 La libreria Leggi_Canali_R_L.h legge il valore analogico in mV fornito prima dal canale passato nei parametri della funzione, calcola il valore della lunghezza della barra in funzione del valore del segnale rilevato e la visualizza, in formato carattere, nel display LCD, ora nella riga 1 ed in seguito nella riga 2 a seconda del canale analogico analizzato.

 

File libreria Leggi_Canali_R_L.h

/**************************************************************
*                                                                                                            
       *
*        Libreria gestione display grafico                                              
            *
*                Versione V1.0                                                                    
       *
*                                                                                                             *
*                MCU 16F876A / 16F877A                                                  *
*                Piattaforma Micro-GT IDE / mini                                        *
*                                                                                                             *
*                                                                                                             *
*      MODULO PER LA CREAZIONE DELL'ARRAY                        *
*      DI CARATTERI DA VISUALIZZARE NEL DISPLAY LCD       *
*                                                                                                             *
*      Autore Giuseppe Bonfiglio                                                             *
*                                                                                                            
 *
*      Creato il 25 febbraio 2014                                                              *
*                                                                                                              
*
*  Attenzione: non superare l'area di stampa                                            *
*                                                                                                              
*
****************************************************************/
  
void scrivi_barra(int can, int r) {

 

                int i;

                float V_canale;

                unsigned int segnale;

                unsigned int barra;

              

                     V_canale = leggi_ad(can);                     // nella libreria ADC.h

                   

                     segnale = (V_canale * 4880) / 1000;           // 357,1428571;         

                     barra = segnale /355;                         // 5000 / 357 = 14,0056

 

                     if(can == 0) {

                          FRASE(r,1,"L               ");                      // L

                       }

                    else {

                          FRASE(r,1,"R               ");                      // R

                        }

        

                     switch (barra) {

                        case 0:

                            FRASE(r,3,FR_0);

                        break;

                        case 1:

                            FRASE(r,3,FR_1);

                        break;

                        case 2:

                            FRASE(r,3,FR_2);

                        break;

                        case 3:

                            FRASE(r,3,FR_3);

                        break;

                        case 4:

                            FRASE(r,3,FR_4);

                        break;

                        case 5:

                            FRASE(r,3,FR_5);

                        break;

                        case 6:

                            FRASE(r,3,FR_6);

                        break;

                        case 7:

                            FRASE(r,3,FR_7);

                        break;

                        case 8:

                            FRASE(r,3,FR_8);

                        break;

                        case 9:

                            FRASE(r,3,FR_9);

                        break;

                        case 10:

                            FRASE(r,3,FR_10);

                        break;

                        case 11:

                            FRASE(r,3,FR_11);

                        break;

                        case 12:

                            FRASE(r,3,FR_12);

                        break;

                        case 13:

                            FRASE(r,3,FR_13);

                        break;

                        case 14:

                            FRASE(r,3,FR_14);

                        break;

 

                    }

}

  

La libreria LCD_2x16-28-PIN.h si incarica di visualizzare nel display LCD tutti i caratteri che vengono trasmessi, analizzando il codice non è difficile comprenderne il significato, pertanto non mi dedicherò più di tanto all’argomento ed eventualmente tratterò la questione in modo più appropriato realizzando un progetto specifico per il display LCD 2 x 16.

 

File: LCD_2x16-28-PIN.h

 /************************************************************
 *                                                                                              *
 *        Libreria gestione display grafico                                *
 *                Versione V1.1                                                      *
 *                                                                                              *
 *                per  PIC con 28 pin                                             *
 *                                                                                              *
 *                MCU 16F876a                                                     *
 *                Piattaforma Micro-GT IDE / mini                        *
 *                                                                                               *
 *         Moduli: CLEAR -> pulisce area display                  *
 *                 Clock -> sincronizza cicli R/W                          *
 *                 Inizializza -> posiziona cursore                        *
 *                 Scrivi ->  Accende caratteri                               *
 *                 vai  -> identifica cella                                          *
 *                 frase -> emette sequenza char                         *
 *                                                                                               *
 *  Autore Ing. Marco Gottardo                                               *
 *  Libreria modificata da Giuseppe Bonfiglio il 28-01-2014  *
 *                                                                                                *
 *  Attenzione: non superare l'area di stampa                       *
 * *************************************************************/

 

void CLEAR(){

                                    RS=0;

                         RW=0;

                                    PORTB=0x01;

                                    CLOCK();

                                    DelayMs(2); // da 2 a 5 millisecondi

 }

 

// **************************************************

void CLOCK(){

                             EN=1;

                             DelayMs(1);

                             EN=0;

}

 

// **************************************************

void INIZIALIZZA(){

            RS=0; RW=0;            PORTB=0x30;             //usa il display in mod. 8 bit

                                   DelayMs(15);

                                                  CLOCK();     //imposto da specifiche tecniche del display

                                                  DelayMs(10); //vanno date in sequenza tre comandi clock()

                                                  CLOCK();

                                                  DelayMs(10);

                                                  CLOCK();

                                                  DelayMs(10);

                                  

                                                  RS=0; RW=0; PORTB=0x38; //conferma interfaccia a 8 bit e font 5x8

                                                  CLOCK();

                                                  DelayMs(1);

 

                                                  RS=0; RW=0; PORTB=0x08; //spegni LCD

                                                  CLOCK();

                                                  DelayMs(1);

 

                                                  RS=0; RW=0; PORTB=0x0C; //accendi LCD

                                                  CLOCK();

                                                  DelayMs(1);

 

                                                  RS=0; RW=0; PORTB=0x01; //pulisci LCD

                                                  CLOCK();

                                                  DelayMs(1);

 

                                                  RS=0; RW=0; PORTB=0x03; //LCD acceso ma toglie cursore e lampeggio

                                                  CLOCK();

                                                  DelayMs(1);

}

 

// **************************************************

void SCRIVI(char lettera){

                                RS=1; RW=0;

                                PORTB=(lettera); //scrive dove posizionato

                                CLOCK();

                                DelayUs(50);

}

 

// **************************************************

void VAI(unsigned char r, unsigned char c){

                   unsigned char a=0;         //posiziona il cursore

                   RS=0; RW=0;

                           if(r==1){a=c+127;}

                           if(r==2){a=c+191;}

                                                PORTB=(a);

                                               CLOCK();

                                    DelayUs(50);

}

 

// **************************************************

void FRASE(unsigned char l, unsigned char n, const char* msg1){

                         while(n<=16){VAI(l,n);

                                        SCRIVI(*msg1++);

                                        n++;

                                        }

 n=1;

 }

 

// **************************************************

Piattaforme usate:

Hardware :

Scheda a Microcontrollore -->Micro-GT mini

Interfaccia-->Vu-Meter stereo shield

Software : MPLAB X IDE v1.80

Compilatore : HI-TECH PICC (v9.81)

Programmatore : Microchip PICkitTM 3

Video del progetto finito e funzionante:

Nel primo video la versione originale a Led, sviluppata da Marco Viesentini. A seguire la mia versione eseguita sul display LCD.

 

 

 

La nuova versione per display LCD 2x16.

 

Questo progetto è ridistribuibile secondo i termini di licenzaCreative Commons Attribuzione-Condividi allo stesso modo 3.0 Italia

  Pagina precedente