Misura del valore efficace

Il firmware descritto, abbinato ad un microcontrollore PIC, consente di effettuare la misura del vero valore efficace e del livello in dB di un qualunque segnale analogico.

Il valore efficace di una grandezza elettrica in corrente alternata è un parametro che ha lo scopo di semplificare i calcoli ingegneristici (al seguente link un approfondimento sugli errori sperimentali) evitando di analizzare ogni istante infinitesimo che costituisce la forma d’onda. Il valore efficace  di una grandezza equivale a quel valore che in regime di tensione continua svilupperebbe la stessa potenza. Un segnale variabile periodico infatti non ha un valore definito di tensione o corrente come nel caso della corrente continua, ma varia istante per istante. Ad esempio sottoponendo un resistore a una corrente alternata di 34 Vpp (cioè di forma d’onda sinusoidale variabile in ampiezza fra +17 e -17 V) si svilupperebbero gli stessi effetti di riscaldamento come se fosse sottoposto a una tensione continua di 12 V. La formula seguente consente di calcolare il valore efficace o RMS (Root Mean Square) di una qualsiasi funzione, data una serie di N valori:

Tale espressione si semplifica nel caso di un segnale sinusoidale:

Molti strumenti di misura, tra cui i multimetri più economici, sono calibrati per mostrare il valore efficace in funzione del valore medio di una tensione sinusoidale raddrizzata. Il metodo funziona bene se il segnale  ha forma d’onda perfettamente sinusoidale, ma dà risultati completamente errati se il segnale è distorto oppure ha una forma d’onda non sinusoidale o presenta una corrente continua sovrapposta. L’errore aumenta con l’aumentare della ricchezza in armoniche del segnale. Alcuni strumenti sono in grado di operare  il calcolo del vero valore efficace, campionando il segnale  ed eseguendo  i calcoli in tempo reale. Questi apparecchi sono contraddistinti dalla sigla true RMS. La realizzazione di uno strumento a vero valore efficace è notevolmente semplificata utilizzando un microcontrollore. Nel Listato 1 è riportato il codice da utilizzare per il calcolo e la visualizzazione del valore efficace di una tensione in ingresso sul pin A1. Inoltre, lo stesso codice effettua anche il calcolo dello stesso valore espresso in dB. L’intero firmware è basato sull’uso del convertitore A/D in ingresso al PIC. Esso effettua  il campionamento di N valori (nella fattispecie  3000) della forma d’onda; le righe di codice da 26 a 29 effettuano la sommatoria dei valori quadrati della funzione campionata

Utilizzando un PIC alimentato a 5V sarà necessario precondizionare il segnale analogico, facendo in modo che le sue variazioni siano comprese tra 0V e 5V. Valori esterni a questo intervallo pregiudicherebbero la correttezza della misura. Come si nota la riga di codice 30 esegue una divisione che a prima vista potrebbe sembrare strana, se non addirittura sbagliata. In realtà tale operazione è necessaria poiché i valori acquisiti con l’ADC del PIC sono unità comprese tra 0 e 255, ma in realtà non esprimono il valore in volt della forma d’onda. Quindi sarà necessario considerare un fattore correttivo che ne tenga conto, secondo la formula seguente:

A questo punto non resta che effettuare la divisone per il numero dei campioni (3000) e la radice quadrata del risultato. Il calcolo del valore efficace espresso in dB è molto semplice ed è eseguito tramite la seguente formula:

I risultati  così ottenuti sono visualizzati tramite porta seriale su di un PC. Ovviamente, utilizzando come visualizzazione un display LCD, per esempio, è facile costruire uno strumento RMS portatile.

// Compilatore: CCS

#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#elif defined(__PCH__)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif

#include <math.h>

void main() {
const long NUM_DATA_POINTS = 3000;
long i;
int value;
float voltage;

printf(“Calcolando…:\r\n”);

setup_port_a( ALL_ANALOG );
setup_adc( ADC_CLOCK_INTERNAL );
set_adc_channel( 1 );

while(TRUE)
{
voltage = 0;
for(i=0; i<NUM_DATA_POINTS; ++i){
value = Read_ADC();
voltage += (float)value*(float)value;
}

voltage /=2601.0;

voltage = sqrt(voltage/(NUM_DATA_POINTS));
printf(“\r\nInput = %f V %f dB\r\n”, voltage, 20*log10(voltage));

}
Listato 1

10 Commenti

  1. Maurizio Di Paolo Emilio Maurizio Di Paolo Emilio 28 febbraio 2017
  2. Marcello Colozzo 2 marzo 2017
      • Marcello Colozzo 3 marzo 2017
          • Marcello Colozzo 3 marzo 2017
    • Marcello Colozzo 3 marzo 2017
      • rromano001 21 marzo 2017
  3. Marcello Colozzo 4 marzo 2017

Scrivi un commento