Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Simulazione tensione raddrizzata

Progetti, interfacciamento, discussioni varie su questa piattaforma.

Moderatori: Foto UtenteMassimoB, Foto Utentexyz, Foto UtenteWALTERmwp

0
voti

[1] Simulazione tensione raddrizzata

Messaggioda Foto Utentelemure64 » 8 mar 2021, 16:55

Ciao Forum

Vorrei mettere in piedi un sistema che mi consenta di monitorare il valore della tensione di rete. L'idea è quella di un trasformatore 230 V => 6 V seguito da un ponte, condensatore di filtro con carico un semplice partitore calcolato in modo di avere un range sufficiente. Non mi serve altissima precisione, vorrei solo capire se ci sono sbalzi di qualche tipo. Giusto per contestualizzare, ogni tanto mi si sconnettono gli hard disk esterni e volevo intanto escludere cadute di tensione troppo brevi per essere avvertite ma sufficienti per creare questo problema. Inoltre non mi dispiace controllare cosa succede.

Per questo motivo penso sia più importante la velocità che la precisione (che peraltro un Arduino da solo non mi darebbe) e direi che un'uscita a intervalli di 200-100 ms dovrebbe permettermi di vedere eventuali fluttuazioni rapide.

Ho deciso di usare una coda per memorizzare i valori e farne la media. Ci sono quindi A) due tempi caratteristici: uno è quello per il polling dei pin e l'altro è quello per la scrittura dei valori in uscita (BTW ciascuna delle due funzioni è chiaramente riscontrabile in "loop"). B) La dimensione dell'array che modella la coda.

Ho scritto lo sketch che accludo e prima di costruire fisicamente il circuito ho pensato di introdurre una sezione di simulazione per fare una prima valutazione. La funzione genera una sinusoide utilizzando un valore del tempo a inizio loop in una variabile globale. Nel momento in cui c'è una differenza assegnata con il valore di picco (positivo o negativo che sia), viene memorizzato l'istante corrispondente. Per valori non compresi nell'intervallo che delimita il picco, utilizzo un decadimento lineare a partire dal valore massimo positivo. Per il calcolo basta semplicemente una diminuzione proporzionale alla differenza di tempo tra quello attuale e il precedente corrispondente al picco.

Come si può vedere dal codice, almeno nelle mie intenzioni questo dovrebbe emulare la sinusoide raddizzata. Pensavo di dimensionare il condensatore di filtro con un tempo caratteristico di 2-3 volte il periodo della tensione di rete, per avere un compromesso tra precisione (quella permessa dal tutto) e la necessità di individuare fluttuazioni rapide.

Purtroppo lo sketch non funziona. Il primo controllo è stato forzare il valore ritornato dalla funzione per i valori estremi, e funziona (se non altro questo mi dice che le istruzioni di scaling variabili dovrebbero essere a posto). Ma a parte questo, nessuna delle combinazioni dei parametri con valori ragionevoli sembra dare numeri sensati. Posso solo intuire che i tre parametri di cui in A e B non solo interagiscono tra loro ma anche con il clock interno. Ovviamente nulla mi assicura sulla corretta "schedulazione" delle varie sezioni ma ho pensato che il modello UNO che sto ora usando sia sufficiente. Probabilmente c'è come minimo qualcosa di assimilabile al problema dell'aliasing ma a questo punto mi sono perso. Ancora più probabilmente c'è qualche errore di concetto nell'implementazione.

In caso di risposta vorrei chiedere di mantenersi su tecniche non dico elementari ma quasi. Come si può facilmente notare a programmazione sto quasi a zero. Inoltre non ho mai usato gli interrupt, per esempio, né timers interni né altro, e non sono una cima in questo tipo di realizzazioni. Se l'errore è solo nel codice e si può far funzionare allora bene; ma nel caso improbabile che il codice vada bene e il problema è che per dirla in modo elementare "controllo e controllore sono la stessa cosa" e che quindi realizzando il circuito fisico risolverei, meglio ancora. Però ovviamente ora non ho modo di saperlo.

Dato che non voglio passare per uno che fa perdere tempo al prossimo, se il problema è più difficile di quelle che sono le mie capacità, anche sapere questo andrà bene e lascerò stare questo specifico progetto; ovviamente è inutile spendere il proprio tempo sapendo che non sarà stato possibile recepire la soluzione proposta (chiaramente se invece il problema è di interesse generale, suppongo il topic prenderà comunque la sua strada indipendentemente dal fatto che possa essere utile a me).

Credo che la scrittura del codice sia abbastanza auto esplicativa, o almeno spero.

Grazie per qualsiasi eventuale risposta.

Codice: Seleziona tutto
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#define              PARX_DEMO_MODE                    1

// ----------------------------------------------------- user parameters

#define              PARX_OUTFMT_CODE                  1   /*
                                                            *  Serial port out format code
                                                            *
                                                            *  0 : row of integers
                                                            *  1 : format for "Serial port plotter by Borislav
                                                            *
                                                            */

#define              PARX_NUM_OF_CHANNELS              4
unsigned int         GV_input_pins [PARX_NUM_OF_CHANNELS] = { A0 , A1 , A2 , A3 } ;

#define              PARX_TIMEQUANTUM                  0   // (ms) wait if nothing done in 'loop'
#define              PARX_READATA_TIMESCAN             5   // (ms) pool pin values interval
#define              PARX_OUTPUT_TIMEINTERVAL        200   // (ms) output time interval

#define              PARX_SERIAL_SPEED              9600
#define              PARX_QUEUES_SIZE                 68   // queue size

#define              PARX_VREAD_MIN                   (2)  // output is   2 V @    0 analog val
#define              PARX_VREAD_MAX                  380   // output is 380 V @ 1023 analog val
#define              PARX_VREADOFFSET                 (0)  // V added to output

// ----------------------------------------------------- internal parameters

#define              PARX_CONV_RESOLUTION_BITS        10   // converter resolution
#define              PARX_READSCALE2EXP                6   // scale factor for internal calculations

// -----------------------------------------------------

#if(  PARX_DEMO_MODE != 0  )
    #include <math.h>

    #define          PARDEBX_POWER_FREQ               50  // (Hz) power frequency
    #define          PARDEBX_DECAY_CONST             120  // (ms) time decay

    const double     GV_DEB_mfact = ((2.0*3.141592654*PARDEBX_POWER_FREQ)/1000.0) ;
    const double     GV_DEB_decayf = 0.5 / (double) PARDEBX_DECAY_CONST ;
#endif


// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %                                                                        %
// %                                                                        %
// %                                                                        %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


char                 GV_first_loop = 0 ;  // reserved
char                 GV_queue_is_valid = 0 ;
unsigned long        GV_time_last_pinread = 0  ;
unsigned long        GV_time_last_output = 0  ;
unsigned long        GV_time_at_loop_start ;
unsigned int         GV_readings [PARX_NUM_OF_CHANNELS][PARX_QUEUES_SIZE] ;
int                  GV_queue_index_pos = -1 ;
unsigned int         GV_fast_ic ;
unsigned int         GV_fast_jc ;
unsigned long        GV_accum ;
unsigned long        GV_scalefac_Adiv ;

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %                                                                        %
// %                                                                        %
// %                                                                        %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#if(  PARX_DEMO_MODE != 0  )

          // 1023 for arduino
          double           GV_DEB_ypts_full = ( (double)( ( 2 << ( PARX_CONV_RESOLUTION_BITS - 1 ) ) - 1 ) / 1.0 ) ;
          // time at sin max/min
          unsigned long    GV_DEB_start_decay [PARX_NUM_OF_CHANNELS] ;

    // emulate analog read with rectified tension

    unsigned int         ret_analog_read (const unsigned int   a_piin)
    {
        unsigned int     res ;
        double           sinres ;
        double           sval ;

        // calculate min/max of Vin, each channel has it own phase shift

        sinres = sin ( ( 0.15 * a_piin ) + ( GV_DEB_mfact * GV_time_at_loop_start ) ) ;

        if(  ( sinres < -0.95  ) || ( sinres > 0.95  )  )
        {
            GV_DEB_start_decay [a_piin] = GV_time_at_loop_start ;
            sval = GV_DEB_ypts_full ;
        }
        else
        {
            sval = ( GV_DEB_ypts_full * ( 1.0 - GV_DEB_decayf * (double)( GV_time_at_loop_start - GV_DEB_start_decay [a_piin] ) ) ) ;
        }


        if(  sval <= 0  )
            res = 667 ;
        else if(  sval > GV_DEB_ypts_full  )  // ISTR DEB
            res = 666 ;
        else
            res = (unsigned int) sval ;

       // FORZATO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        res = 1023 ;

        return (res) ;
    }

#endif


// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %                                                                        %
// %                                                                        %
// %                                                                        %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


void     setup ()
{
    #if(  PARX_DEMO_MODE != 0  )
        for(  unsigned int  icc = 0 ; icc < PARX_NUM_OF_CHANNELS ; icc++  )
            GV_DEB_start_decay [icc] = 0 ;
    #endif

    // scale factor

    GV_scalefac_Adiv = (unsigned long) ( ( (double)( PARX_QUEUES_SIZE ) *
                                           (double)( 2 << (PARX_READSCALE2EXP-1) ) *
                                           (double)( ( 2 << (PARX_CONV_RESOLUTION_BITS-1) ) - 1 ) ) /
                                         ( (double)( PARX_VREAD_MAX - PARX_VREAD_MIN ) ) ) ;


    // what else?

    Serial.begin (PARX_SERIAL_SPEED) ;

    while(  !Serial   )
    {
        ;
    }

    delay (10) ;
}


// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %                                                                        %
// %                                                                        %
// %                                                                        %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


void     loop ()
{
    char               flag_taskrun = 0 ;
    long               calcd_value ;
    unsigned int       outval ;


    GV_time_at_loop_start = millis () ;

    // read pin values and store in the queue

    if(  ( GV_time_at_loop_start - GV_time_last_pinread ) >= PARX_READATA_TIMESCAN  )
    {
        GV_queue_index_pos++ ;

        if(  GV_queue_index_pos >= PARX_QUEUES_SIZE  )
        {
            GV_queue_index_pos = 0 ;

            if( !GV_queue_is_valid  )
                GV_queue_is_valid = 1 ;
        }

        for(  GV_fast_ic = 0 ; GV_fast_ic < PARX_NUM_OF_CHANNELS ; GV_fast_ic++  )
        {
            #if(  PARX_DEMO_MODE != 0  )
                GV_readings [GV_fast_ic][GV_queue_index_pos] = ret_analog_read (GV_fast_ic) ;
            #else
                GV_readings [GV_fast_ic][GV_queue_index_pos] = analogRead (GV_input_pins[GV_fast_ic]) ;
            #endif
        }

        GV_time_last_pinread = GV_time_at_loop_start ;
        flag_taskrun = 1 ;
    }

    // write output values

    if(    ( ( GV_time_at_loop_start - GV_time_last_output ) >= PARX_OUTPUT_TIMEINTERVAL )
        && ( GV_queue_is_valid                                                 )   )
    {
        #if(  PARX_OUTFMT_CODE == 1  )
            Serial.print ("$") ;
        #endif

        for(  GV_fast_ic = 0 ; GV_fast_ic < PARX_NUM_OF_CHANNELS ; GV_fast_ic++  )
        {
            GV_accum = 0 ;

            for(  GV_fast_jc = 0 ; GV_fast_jc < PARX_QUEUES_SIZE ; GV_fast_jc++  )
            {
                GV_accum += ( ( 2 << (PARX_READSCALE2EXP-1) ) * (unsigned long)( GV_readings [GV_fast_ic][GV_fast_jc] ) ) ;
            }

            calcd_value = ( (long)GV_accum / GV_scalefac_Adiv + PARX_VREAD_MIN ) + PARX_VREADOFFSET ;

            if(    ( calcd_value >= 0 )
                && ( calcd_value <= ( ( 2 << ( PARX_CONV_RESOLUTION_BITS - 1 ) ) - 1 ) )   )
                outval = (unsigned int) calcd_value ;
            else
                outval = 0 ;

            Serial.print (outval) ;

            if(  GV_fast_ic < ( PARX_NUM_OF_CHANNELS - 1 )  )
                Serial.print (" ") ;
        }

        #if(  PARX_OUTFMT_CODE == 1  )
            /*
            Serial.print (" :: ") ;
            Serial.print (GV_DEB_ypts_full) ;
             */
            Serial.println (";") ;
        #else
            Serial.println () ;
        #endif

        GV_time_last_output = GV_time_at_loop_start ;
        flag_taskrun = 1 ;
    }


    if( flag_taskrun == 0 )
    {
        #if(  PARX_TIMEQUANTUM > 0  )
            delay (PARX_TIMEQUANTUM) ;
        #endif
    }


    GV_first_loop = 1 ;
}
Avatar utente
Foto Utentelemure64
630 2 6
Stabilizzato
Stabilizzato
 
Messaggi: 347
Iscritto il: 23 giu 2020, 12:26

0
voti

[2] Re: Simulazione tensione raddrizzata

Messaggioda Foto Utentelemure64 » 8 mar 2021, 20:10

Chiedo scusa per l'aggiunta, non è assolutamente per mettere in evidenza il post, ma solo per aggiungere qualche info, dal momento che è scaduto il tempo per l'editazione. Mi ero completamente scordato di avere un generatore di segnali poco sopra la mia testa ed è stato un attimo accenderlo e collegarlo al pin. Purtroppo non ha la possibilità di simulare esattamente la tensione raddrizzata e (volutamente mal) filtrata ma ho potuto impostare una sinusoide a 50 Hz con 1 Vpp e un offset anch'esso pari a 1 V.

Ecco la schermata del risultato. Qualcosina è andato a posto, la tensione che ci si poteva aspettare di leggere è grossomodo quella corrispondente all'ingresso e ho provato con due valori dell'intervallo di polling, come in foto. Si può anche vedere la breve pressione del pulsante di on/off segnale, rapida per quanto ho potuto, il che mi conferma che arduino sta leggendo l'input. L'intervallo di scrittura su seriale è sempre 200 ms in entrambi i casi, e coda di 16 valori in entrambi i casi.

Ora mi pare che il problema sia più di teoria dei segnali che di arduino, solo che è la classica materia che capisco finché leggo ma poi quando serve qualcosa sottomano non la si sa mai (ovviamente vale per me). Non so però spiegarmi la differenza tra i due casi; delle due mi aspetto fluttuazioni maggiori con un intervallo di polling maggiore mentre è evidente che accade il contrario, anche se intravedo la ragione perché non debba essere così. In entrambi i casi non mi pare aliasing perché la frequenza di lettura dal pin è sicuramente più del doppio di 50 Hz, forse è qualcosa di simile a un battimento ma non so con cosa.

Con l'occasione: fino a quanto posso arrivare con Arduino e lo sketch che ho scritto? Sono abbastanza fortunato da dover passare ai microsecondi per il polling o 1 ms è il minimo a cui posso (se mai) aspirare?

Sono veramente perplesso; e scusate ancora per l'"up" non voluto.
Allegati
effetto_dt_coda.jpg
Avatar utente
Foto Utentelemure64
630 2 6
Stabilizzato
Stabilizzato
 
Messaggi: 347
Iscritto il: 23 giu 2020, 12:26

1
voti

[3] Re: Simulazione tensione raddrizzata

Messaggioda Foto Utenteelfo » 8 mar 2021, 21:28

lemure64 ha scritto:L'intervallo di scrittura su seriale è sempre 200 ms in entrambi i casi, e coda di 16 valori in entrambi i casi

Tensione_raddrizzata.jpg

Che numeri sono?
Che curva e'?
Puoi disegnare l'hardware della misura?
Avatar utente
Foto Utenteelfo
4.332 2 5 7
Master
Master
 
Messaggi: 1895
Iscritto il: 15 lug 2016, 13:27

0
voti

[4] Re: Simulazione tensione raddrizzata

Messaggioda Foto Utentelemure64 » 8 mar 2021, 22:14

Se serve il disegno lo faccio ma è semplicemente l'uscita di un Rigol DG1022 connessa a un Arduino UNO; calza al negativo di UNO, centrale al pin A0, l'Arduino è alimentato solo dalla connessione USB.

I numeri che escono sono dovuti agli estremi della scala scelti, ovviamente parametrizzati. L'uscita (il valore scritto scritta sulla seriale) è tale che vale PARX_VREAD_MIN per valore letto zero sul pin, e PARX_VREAD_MAX per la lettura 1023. Ho scelto 0 e 380 perché quest'ultimo è circa il valore di picco della tensione di rete. Mi aspetto ovviamente che la coda faccia automaticamente la media ma per cominciare ho usato il valore massimo che è teoricamente possibile leggere.

Nel frattempo ho fatto altri esperimenti e ho pensato al fatto che partire con 1 Vpp e 1 V di offset, come ho fatto per la schermata, vuol dire praticamente non filtrare dopo il ponte. Con un valore di 100 mVpp (sempre 1 V di offset) mi aspetto di simulare l'effetto del condensatore, poi chiaramente ci sarà da fare un conto e suppongo qualche prova per trovare il compromesso tra stabilità della media mobile e reattività. Appena potrò, proverò a realizzare il circuito effettivo a meno del trasformatore, almeno in questa fase, il Rigol può fornire la tensione necessaria dato che arriva ai 5 V di Arduino. E con un "ripple" di 100 mV va bene.

Insomma, all'atto pratico funziona come mi aspetto: curva praticamente piatta e il tutto reagisce a rapidi ON/OFF. Ma resta per me aperta la questione del perché anche con una combinazione tra dimensione della coda e intervallo di lettura che a conti fatti copre qualche periodo della tensione di rete, i numeri sono sballati. Succede anche con la configurazione di prova che ho descritto ma teoricamente non dovrebbe. Da questo punto di vista sono tuttora curioso di capire cosa succede.
Avatar utente
Foto Utentelemure64
630 2 6
Stabilizzato
Stabilizzato
 
Messaggi: 347
Iscritto il: 23 giu 2020, 12:26

0
voti

[5] Re: Simulazione tensione raddrizzata

Messaggioda Foto Utentestefanopc » 8 mar 2021, 22:31

Perché la raddrizzi?
I diodi non introducono un errore?
Potresti misurare in alternata cercando il valore massimo tutto via sw.
Attento al trasformatore che se è a vuoto e magari progettato al risparmio potrebbe essere vicino alla saturazione e falsare la misura.
Valuta un piccolo toroidale o uno da 380 V da utilizzare a 220 V.
Altrimenti ci sono raddrizzatori di precisione e/o sincroni con cui avere un approccio più adatto.
La coda cosa sarebbe?
Sarà un array?

Ciao
600 Elettra
Avatar utente
Foto Utentestefanopc
3.360 2 5 12
Expert EY
Expert EY
 
Messaggi: 1057
Iscritto il: 4 ago 2020, 9:11

0
voti

[6] Re: Simulazione tensione raddrizzata

Messaggioda Foto Utenteelfo » 8 mar 2021, 22:47

lemure64 ha scritto:I numeri che escono sono dovuti agli estremi della scala scelti, ovviamente parametrizzati. L'uscita (il valore scritto scritta sulla seriale) è tale che vale PARX_VREAD_MIN per valore letto zero sul pin, e PARX_VREAD_MAX per la lettura 1023. Ho scelto 0 e 380 perché quest'ultimo è circa il valore di picco della tensione di rete. Mi aspetto ovviamente che la coda faccia automaticamente la media ma per cominciare ho usato il valore massimo che è teoricamente possibile leggere.

Ok per I numeri ma:

- perche' la curva del post [3]
- perche' la media
- perche' livellare con il condensatore

Prova a guardare:

Low frequency transformer based SOHO UPS design

https://www.infineon.com/dgdl/Infineon- ... 6475d04a5d
UPS.jpg
Avatar utente
Foto Utenteelfo
4.332 2 5 7
Master
Master
 
Messaggi: 1895
Iscritto il: 15 lug 2016, 13:27

0
voti

[7] Re: Simulazione tensione raddrizzata

Messaggioda Foto Utentenicsergio » 9 mar 2021, 9:13

lemure64 ha scritto:Vorrei mettere in piedi un sistema che mi consenta di monitorare il valore della tensione di rete.


Se vuoi un progetto con Arduino già pronto, puoi seguire quello del team OpenEnergyMonitor, usando un trasformatore 230V->9V senza raddrizzare (come dice Foto Utentestefanopc).
La libreria EmonLibCM "spinge" Arduino al limite, impostando un clock ADC di 104us, attivando un interrupt ad ogni conversione e raccogliendo 9615 campioni al secondo. E' pensata per la misurazione di energia attiva, quindi presa "as is" senza modifiche si deve configurare almeno un canale di misura di corrente, a cui basta portare un segnale fisso. In questo modo si ottengono circa 96 campioni sul periodo, dai quali viene calcolato il valore efficace.
Con la proprietà datalog_period imposti ogni quanto farti restituire il valore efficace mediato, la libreria è stata testata con valori da 100ms fino a 5 minuti.
Io ho calibrato il sistema con un fluke e ne sono soddisfatto, come trasformatore avevo usato l'equivalente di questo.
:(){ :|:& };:
Avatar utente
Foto Utentenicsergio
1.690 1 6 13
Expert EY
Expert EY
 
Messaggi: 217
Iscritto il: 1 gen 2020, 16:42

1
voti

[8] Re: Simulazione tensione raddrizzata

Messaggioda Foto UtentePietroBaima » 9 mar 2021, 9:29

Io non utilizzerei un trasformatore per monitorare la tensione di rete.

La ragione di questo è che la tensione di rete non è per nulla una sinusoide, ma un’onda storta forse quasi saturata ai massimi e minimi e quasi lineare in mezzo. :D
Va trattata come un segnale quasi periodico che con la sinusoide non c’entra nulla o quasi.

Se dovessi fare un monitor di rete cercherei di farlo seriamente, dividendo il circuito in due: una parte di acquisizione senza molta intelligenza, dove, essendo non isolato da rete, acquisirei il segnale per poi trasmetterlo in digitale ad una seconda sezione, isolata galvanicamente, che si occuperebbe di fare tutto il signal processing.

Ciao
Pietro
Generatore codice per articoli:
nomi
emoticon
citazioni
formule latex
Avatar utente
Foto UtentePietroBaima
82,6k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 10609
Iscritto il: 12 ago 2012, 1:20
Località: Londra

0
voti

[9] Re: Simulazione tensione raddrizzata

Messaggioda Foto UtenteMarcoD » 9 mar 2021, 10:20

Il suggerimento di Pietro è corretto: la forma d'onda all'uscita di un trasformatore non è esattamente quella in ingresso se l'ingresso non è esattamente sinusoidale.

vuoi rilevare i "buchi" di tensione, ma di quale ampiezza e quale durata ?
Vuoi rilevare un singolo picco (semisinusoide) mancante ?
Vorresti poi riportare il tempo assoluto in hms dell'evento?

Mi sono incuriosito e mi sono divertito a studiare una possibile soluzione,
accrocchierei qualcosa di semplificato come segue:

Va bene raddrizzare a doppia semionda la tensione 50 Hz in modo da avere una tensione pulsante sempre positiva applicata all'ingresso di arduino.
La caduta di tensione ai capi dei diodi, dell'ordine di 2 x 0,6 V, non è nota con prcisione, ma è costante.

Campionerei la tensione pulsante ogni 1 ms,
ogni 10 campioni selezionarei quello maggiore, che rappresente il picco nella semionda.

Campionando con 10 campioni corro il rischio che nel caso più sfavorevole il campione massimo sia spostato di (1/2)x(180°/10) = 9 ° rispetto al massimo della tensione
per cui invece che trovare il massimo, potrei trovare il sen(90° - 9°) = 0,987 , ossia commetteri un errore dell' 1,3 % in meno.
Il dispositivo potrebbe essere sensibile a "buchi " di tensioni minori del 10% del valore di durata prossima al semiperiodo.

Per segnalare il buco, se non si vuole perdere tempo con la trasmissione seriale, si potrebbe anche accendere uno o più LED di segnalazione per qualche secondo.
Poi se arduino accede a un orologio digitale, può inviare il tempo dell'evento.

Non ho esaminato il sorgente, è troppo faticoso leggere in una finestra e cercare di capire.

Per la simulazione della sinusoide anni fa adoperavo l'algoritmo:

X = X + K*Y; Y = Y - K*X;
//X seno, Y coseno
// con valori iniziali X = 0; Y = 1;
// K molto minore di 1 racchiude intervallo campionamento e pulsazione
XR = abs/X); // XR uscita radddrizzata
O_/
Avatar utente
Foto UtenteMarcoD
8.446 4 9 13
Master EY
Master EY
 
Messaggi: 3879
Iscritto il: 9 lug 2015, 16:58
Località: Torino

0
voti

[10] Re: Simulazione tensione raddrizzata

Messaggioda Foto Utentelemure64 » 10 mar 2021, 20:57

Grazie a tutti, ottime idee in ciascun post. Foto Utenteelfo non so spiegarmi i numeri che hai ottenuto presumo caricando lo sketch su un tuo arduino; teoricamente col sorgente dovrebbe essere sempre lo stesso valore dato che a solo scopo di prova ho forzato il valore tornato dalla variabile ma dato che non conosco il subversioning temo di non aver avuto cura di annotare ogni cambiamento.

Nel frattempo è accaduto quello che non speravo, ovvero mi ha funzionato QT, erano anni che ogni tanto provavo ma senza risultato (era un "\" nel path mentre ci voleva la versione della stringa con "/"). In questo tempo ho sempre implementato su arduino quello che dovrebbe essere competenza dell'elaborazione. Ora che mi si apre il mondo QT, se riesco a imparare a ottenere un'interfaccia decente, Arduino dovrà solo fare da passamano leggendo i pin e scrivendo (spero si possa fare in binario) sulla seriale, quindi mi resta solo il dubbio sul perché di quella specie di battimento. E' un probema di campionamento e chi sa cos'altro; proverò a darne una descrizione astratta in modo che possa poi presentare la questione nella sezione del forum dedicata ai segnali.

Ovviamente ho stampato il thread per mettere da parte le idee venute fuori e ringrazio :)
Avatar utente
Foto Utentelemure64
630 2 6
Stabilizzato
Stabilizzato
 
Messaggi: 347
Iscritto il: 23 giu 2020, 12:26


Torna a Arduino

Chi c’è in linea

Visitano il forum: Nessuno e 3 ospiti