Se sei già registrato           oppure    

Orario: 07/05/2024 10:38:29  

 

Energia Alternativa ed Energia Fai Da Te > Applicazioni E Realizzazioni Pratiche

VISUALIZZA L'ALBUM

Pagine: (167)  < ...  86   87   88   89   90   91   92   93   94   95   [96]   97   98   99   100   101   102   103   104   105   106  ...>    (Ultimo Msg)


Homemade Inverter "modulo DC/AC"
FinePagina

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 30/03/2015 11:31:48

Inverter90 ho un modo di procedere ed affrontare i problemi che è il tuo opposto...

Generalmente, quanto devo affrontare qualcosa cerco prima di avere un quadro completo delle possibilità e poi passo alla pratica, vedo che tu fai il contrario...

Direi che con questo progetto il tuo metodo non funziona !

Dobbiamo prima capire bene ciò che vogliamo fare e poi lo facciamo...

Da quando ho postato il codice dove ho provato a implementare il DeadTime c'è stata una domanda che mi ha assillato fino ad ora: "Ma se è così semplice, perchè la scheda EG8010 implementa il DeadTime ?"

Se un cinese che ha realizzato una scheda funzionante l'ha considerato vuol dire che è un problema reale, in qualche modo va considerato e gestito...

Così mi sono messo a studiare ed ho trovato un piccolo sito internet di Francesco Parisi dove viene affrontato il discorso dei timer su AVR con maggiore dettaglio:

http://telpar.altervista.org/AVR/ATmega8/AVR-libC/

In realtà leggendo i sei paragrafi e ragionando un po' mi sono reso conto che nel mio codice e nei miei disegni il problema del DeadTime non è presente perchè tutti i miei ragionamenti si sono basati su 2 punti fermi:

1) Il numero di campioni di una semionda è identico al numero di elementi del vettore;
2) Intendiamo pilotare il ponte ad "H" solo con PWM, senza onda quadra.

Questi due punti fermi permettono di risolvere il problema del DeadTime poichè nel passaggio per lo "0" ci sarà sempre un campione di "x" µS in cui tutti i Pin sono a 0.

Quindi quando scriviamo il codice ne dobbiamo tenere conto...

Ma allora perchè la scheda EG8010 contempla il DeadTime ? (http://www.egmicro.com/download/EG8010_datasheet_en.pdf)

Perchè, ad esempio, se il numero di campioni non corrisponde al numero di elementi del vettore può capitare che nell'ultimo intervallo di campionamento di 40 µS l'onda del PWM si trova sfasata rispetto alla chiamata dell'ISR.
Forse con una immagine si capisce meglio:

http://www.energialternativa.info/public/newforum/ForumEA/D/PWM_1_1.png



In questo caso, specialmente se usiamo il pilotaggio con onda quadra, prima di attivare i finali della semionda negativa dobbiamo aspettare lo spegnimento dei finali dell'onda positiva.

Assodato questo punto andiamo avanti.

Il sabato e la domenica, per impegni familiari, non riesco a scrivere sul Forum, ma col cell vi leggo e, tra un post e l'altro, mi è venuto in mente che per rendere il nostro codice più flessibile sarebbe funzionale implementare l'uscita quadra a 50 Hz per chi vuole utilizzare/sperimentare l'altro metodo di pilotaggio del ponte H, ovvero PWM su 2 finali, QUADRA sugli altri 2.

Quindi nello sviluppo del codice dovremo contemplare anche tale funzionalità

Per il PID che hai postato, non ho controllato: verificare i tuoi schemi e i tuoi codici richiede tempo e, al momento, quel poco che ho cerco farlo fruttare al meglio.
Non te la prendere, ma già lo sai che ancora presto per pensare al PID, non sappiamo nemmeno se il codice genera una sinusoide !

Il codice che ho postato non è quello definitivo ma è solo un preliminare per iniziare ad affrontare seriamente le varie problematiche come DeadTime, messa in fase con la rete Enel e aspetti nascosti.

Per esempio, ancora non mi è chiaro se è conveniente utilizzare un PWM Fast o uno a Correzione di Fase...

Inoltre sul sito di Parisi linkato sopra, nell'articolo riguardante il Timer2, viene accennato alla possibilità di PWM Fast con regolazione lineare di DutyCycle e Frequenza !

Prima di andare avanti c'è un problema da gestire: come aumentare o diminuire la frequenza di qualche HZ ?
E, quando effettuiamo tale variazione, cosa succede ai vari segnali (PWM, Onda Uscita, Istanti di Campionamenti, etc.) dell'immagine sopra ?

Sarei felice e mi sarebbe parecchio d'aiuto confrontarmi con qualcuno che ha già affrontato questi argomenti quindi fatevi avanti !!!



Modificato da BellaEli - 30/03/2015, 11:55:19


---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 30/03/2015 12:40:40

Continunando nel ragionamento, ipotizziamo di utilizzare il Timer1 in modalità Fast PWM con il seguente classico schema:

http://www.energialternativa.info/public/newforum/ForumEA/D/PWM2.png



Ipotizziamo di impostare il prescaler a 1, con Clock 16 MHz avremo un ciclo ogni 62,5 nS, quindi:

62,5 * 512 = 32.000 nS = 32 µS

Un tempo di campionamento che mi sembra equilibrato.

Qiundi riferendoci all'immagine N = 511 (infatti i 512 valori vanno da 0 a 511)

Ora modificando il valore di NA, quindi sullo stesso Timer1, potremo variare il DutyCycle di uscita con una precisione di 512 valori che mi sembrano altrettanto buoni: una giusta via di mezzo tra tempo di campionamento e risoluzione !

In questo modo, variando il valore di NA possiamo variare il DutyCycle, variando il valore di N possiamo variare la frequenza.

I valori di NA li variamo in base a quelli inseriti nel vettore che, nello specifico, sarà di 625/2 elementi.

NOOO !!! Numero di campioni dispari, vettore non simmetrico, tutto da rifare !!!

Ok allora torniamo ai nostri 40 µS, abbiamo:

62,5 nS * 640 = 40.000 nS = 40 µS

Quindi il nostro N sarà = 639 (infatti i 640 valori vanno da 0 a 639)

Ora modificando il valore di NA, quindi sullo stesso Timer1, potremo variare il DutyCycle di uscita con una precisione di 640 valori che mi sembrano più che buoni: equilibrio tra tempo di campionamento e risoluzione !

Variando il valore di NA possiamo variare il DutyCycle, variando il valore di N possiamo variare la frequenza.

I valori di NA li variamo in base a quelli inseriti nel vettore che, nello specifico, sarà di 500/2 elementi (250 elementi).

Ora come si fa ad aumentare o diminuire la frequenza ? Dobbiamo modificare il valore di N, ovvero il 639 aumentandolo o diminuendolo.

Proviamo: N = 638

62,5 nS * 639 = 39.9375 µS

che corrisponde ad una frequenza di 50.078 Hz

Bellissimo !!!

Possiamo variare molto facilmente la frequenza di qualche frazione di Hz semplicemente variando il valore di N e se tale variazione la applichiamo nel passsaggio per lo 0 non introdurremo alcuna distorzione.

Abbiamo una ottima risoluzione di 640 valori, che corrispondono a circa 0,35 Vac

Gestiamo senza problemi DeadTime e onda QUADRA per il pilotaggio alternativo.

Mi sembra tutto troppo bello, Elettro mi dici dove sto sbagliando ?!?!?



Modificato da BellaEli - 30/03/2015, 13:20:21


---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 30/03/2015 14:25:05

Mi sorge un dubbio: ma posso modificare il valore di ICR1 (ovvero il valore di N) in runtime ???



Modificato da BellaEli - 30/03/2015, 15:17:13


---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

inverter90

Avatar
MegaWatt


Gruppo:Utente
Messaggi:323

Stato:



Inviato il: 30/03/2015 15:18:28


CITAZIONE

Inverter90 ho un modo di procedere ed affrontare i problemi che è il tuo opposto...

Generalmente, quanto devo affrontare qualcosa cerco prima di avere un quadro completo delle possibilità e poi passo alla pratica, vedo che tu fai il contrario...

Direi che con questo progetto il tuo metodo non funziona !


si BellaEli ai ragione inutili andare avanti senza essere sicuri di quello che si sta facendo il mio era solo un modo per passare il tempo so anche che lo schema anche se fosse buono al momento non serve a niente

CITAZIONE
Da quando ho postato il codice dove ho provato a implementare il DeadTime c'è stata una domanda che mi ha assillato fino ad ora: "Ma se è così semplice, perchè la scheda EG8010 implementa il DeadTime ?"


la mia era solo una domanda appunto, deadTime timer ecc.. non posso affermare niente perche quello che sto imparando lo sto imparando da voi, (io sono solo un perito meccanico che lavora come manutentore) e cerco di aprirmi nel mondo dell'elettronica e se si può dire programmazione..

CITAZIONE
Non te la prendere, ma già lo sai che ancora presto per pensare al PID, non sappiamo nemmeno se il codice genera una sinusoide !


Ma assolutamente siamo su un forum dalle idee libere e niente è dovuto...

CITAZIONE
Per esempio, ancora non mi è chiaro se è conveniente utilizzare un PWM Fast o uno a Correzione di Fase...


Ecco si questa cosa ad esempio non mi è chiara nemmeno a me quale modalità è meglio e quale possa essere la differenza tra le 2. Fast pwm dovrebbe essere a dente di sega e phase correct triangolare, sul risultato finale è ininfluente?


CITAZIONE
Mi sorge un dubbio: ma posso modificare il valore di OCR1A in runtime ???


Il valore OCR1A e OCR1B non lo modifichiamo gia con la tabella?



---------------
Il niente è impossibile finchè non ci provi!!!

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 30/03/2015 17:25:46


CITAZIONE

Il valore OCR1A e OCR1B non lo modifichiamo gia con la tabella?


Ho modificato il messaggio, avevo sbagliato registro, mi riferivo a ICR1, non OCR1x...



---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 30/03/2015 17:57:13

Ragazzi perdonatemi ma nonostante tutte le guide lette finora faccio ancora fatica a districarmi nei registri dei timer...

Riferendomi alla seguente immagine

http://www.energialternativa.info/public/newforum/ForumEA/D/PWM2.png



vorrei le seguenti impostazioni:

1) PWM settato come "phase and frequency correct";

2) Timer1 conti da 0 a "X" (un valore impostato da me, che da quanto ho capito dovrebbe essere ICR1, e tale valore lo devo modificare in runtime per potermi agganciare alla fase della rete Enel);

3) Ogni volta che il Timer1 raggiunga il valore "X" da me impostato, venga richiamata la ISR (al cui interno ci sarà il codice per setteare i registri OCR1x per il PWM). Come si chiamerà la ISR ? TIMER1_OVF_vect ?;

4) L'uscita del PWM del Pin 9 deve essere in funzione del valore del registro OCR1A e quella del Pin 10 del registro OCR1B.

Qualcuno mi spiega come settare i registri ???



---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

inverter90

Avatar
MegaWatt


Gruppo:Utente
Messaggi:323

Stato:



Inviato il: 30/03/2015 18:32:03

ma tu vuoi utilizzare un solo timer? Sia per i pwm che per gl'interrupt?



---------------
Il niente è impossibile finchè non ci provi!!!

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 30/03/2015 18:34:09

Si !

Utilizzando il solo Timer1 ho l'impressione di riuscere ad avere un controllo più completo e granulare di ogni situazione...



---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

inverter90

Avatar
MegaWatt


Gruppo:Utente
Messaggi:323

Stato:



Inviato il: 30/03/2015 19:01:39

Ok allora se ho capito bene dovrebbe essere cosi (ma attendiamo conferme)


TCCR1A = (1 << COM1A1)|(1 << COM1B1) ;//entrambe le uscite non invertite

TCCR1B = (1 << WGM13) | (1 << CS10);//WGM13 IMPOSTA PWM PHASE FREQUENZA CORRETTA ICR1/ CS10 IMPOSTA PRESCALER 1

ICR1 =X;//RICHIAMA LA ISR OGNI TOT(X)

TIMSK2 = (1 << OCIE2A); //ABILITA LE INTERRUZIONI QUANDO ICR1 RAGGIUNGE X

sei();//ABILITA L'HARDWARE A RICEVERE L'INTERRUZIONI

ISR (TIMER1_COMPA_vect) {

}


??????



---------------
Il niente è impossibile finchè non ci provi!!!

 

inverter90

Avatar
MegaWatt


Gruppo:Utente
Messaggi:323

Stato:



Inviato il: 30/03/2015 19:18:41

LINK

LINK

Forse possono essere utili



---------------
Il niente è impossibile finchè non ci provi!!!

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 30/03/2015 20:07:57

Per il momento sto testando il seguente codice:

<font size="-1">
#include <avr/io.h>
#include < avr/interrupt.h >
#include < avr/pgmspace.h >

volatile int Indice = 0;

prog_char onda[251] PROGMEM =
{0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 99, 104, 109, 114, 119, 124, 128, 133, 138, 143, 147, 152, 157, 161, 166, 170, 175, 179, 184, 188, 193, 197, 201, 206, 210, 214, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255, 259, 263, 266, 270, 274, 277, 281, 285, 288, 292, 295, 298, 302, 305, 308, 311, 315, 318, 321, 324, 327, 329, 332, 335, 338, 340, 343, 346, 348, 351, 353, 355, 358, 360, 362, 364, 366, 368, 370, 372, 374, 375, 377, 379, 380, 382, 383, 385, 386, 387, 389, 390, 391, 392, 393, 394, 395, 395, 396, 397, 397, 398, 398, 399, 399, 399, 400, 400, 400, 400, 400, 400, 400, 399, 399, 399, 398, 398, 397, 397, 396, 395, 395, 394, 393, 392, 391, 390, 389, 387, 386, 385, 383, 382, 380, 379, 377, 375, 374, 372, 370, 368, 366, 364, 362, 360, 358, 355, 353, 351, 348, 346, 343, 340, 338, 335, 332, 329, 327, 324, 321, 318, 315, 311, 308, 305, 302, 298, 295, 292, 288, 285, 281, 277, 274, 270, 266, 263, 259, 255, 251, 247, 243, 239, 235, 231, 227, 223, 219, 214, 210, 206, 201, 197, 193, 188, 184, 179, 175, 170, 166, 161, 157, 152, 147, 143, 138, 133, 128, 124, 119, 114, 109, 104, 99, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 45, 40, 35, 30, 25, 20, 15, 10, 5, 0}; 

void setup() {

  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT); 
  
  ICR1  = 640;                                <span style="color: gray;">// Setto il periodo a 40 µS (con Fck 16,0 Mhz, Prescaler 1)</span>

  TCCR1A |= (1 << WGM11);                     <span style="color: gray;">// Setto la modalità Fast PWM a risoluzione variabile</span>
  TCCR1B |= (1 << WGM12) | (1 << WGM13);

  TCCR1A |= (1 << COM1A1) | (1 << COM1B1);    <span style="color: gray;">// Imposto le uscite 9 e 10 come non invertenti</span>

  TCCR1B |= (1 << CS10);                      <span style="color: gray;">// Imposto il Prescaler a 1</span>
  
  TIMSK1 |= (1 << TOIE1);                     <span style="color: gray;">// Abilito ISR su OverFlow</span>

  sei();

}

void loop() {
  
}


ISR (TIMER1_OVF_vect){

  if ((Indice < 1) || (Indice = 250) || (Indice > 499)) {	<span style="color: gray;">// Indice 0, 250 o 500 (Valore 0, incrocio delle semionde) </span>
    OCR1A = 0;
    OCR1B = 0;
   }

  if ((Indice > 0) && (Indice < 250)) {				<span style="color: gray;">// Indice compreso tra 1 e 249 (Valori tra 5..400..5) </span>
    OCR1A = pgm_read_byte(&onda[Indice]);
  }

  if ((Indice > 250) && (Indice < 500)) {			// Indice compreso tra 1 e 249 (Valori tra 5..400..5) 
    OCR1B = pgm_read_byte(&onda[Indice - 250]);
  }

  if (Indice > 499) {						<span style="color: gray;">// Se l'indice è = 500 lo resetto per ricominciare il ciclo</span>
    Indice = 1;
  }
  else {
    Indice++;							<span style="color: gray;">// Incremento l'Indice</span>
  }

}
</font>


Ma sembra che la ISR non venga mai chiamata...

Elettro mi dai una mano ?



---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

ElettroshockNow

Avatar
GigaWatt


Gruppo:Utente
Messaggi:4656

Stato:



Inviato il: 31/03/2015 03:38:40

Eccomi ..
Ho trovato un errore :
if ((Indice < 1) || (Indice = 250) || (Indice > 499)) { // Indice 0, 250 o 500 (Valore 0, incrocio delle semionde)
e alcune cosette che non servivano più ,tipo il Progmem

Ora il codice funziona e genera quasi una sinusoide ...


----------------------------------------------------------------------------------------------------------------------------------

int Indice = 0;

const int onda[251]=
{0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 99, 104, 109, 114, 119, 124, 128, 133, 138, 143, 147, 152, 157, 161, 166, 170, 175, 179, 184, 188, 193, 197, 201, 206, 210, 214, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255, 259, 263, 266, 270, 274, 277, 281, 285, 288, 292, 295, 298, 302, 305, 308, 311, 315, 318, 321, 324, 327, 329, 332, 335, 338, 340, 343, 346, 348, 351, 353, 355, 358, 360, 362, 364, 366, 368, 370, 372, 374, 375, 377, 379, 380, 382, 383, 385, 386, 387, 389, 390, 391, 392, 393, 394, 395, 395, 396, 397, 397, 398, 398, 399, 399, 399, 400, 400, 400, 400, 400, 400, 400, 399, 399, 399, 398, 398, 397, 397, 396, 395, 395, 394, 393, 392, 391, 390, 389, 387, 386, 385, 383, 382, 380, 379, 377, 375, 374, 372, 370, 368, 366, 364, 362, 360, 358, 355, 353, 351, 348, 346, 343, 340, 338, 335, 332, 329, 327, 324, 321, 318, 315, 311, 308, 305, 302, 298, 295, 292, 288, 285, 281, 277, 274, 270, 266, 263, 259, 255, 251, 247, 243, 239, 235, 231, 227, 223, 219, 214, 210, 206, 201, 197, 193, 188, 184, 179, 175, 170, 166, 161, 157, 152, 147, 143, 138, 133, 128, 124, 119, 114, 109, 104, 99, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 45, 40, 35, 30, 25, 20, 15, 10, 5, 0};

void setup() {
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
ICR1 = 640; // Setto il periodo a 40 µS (con Fck 16,0 Mhz, Prescaler 1)
TCCR1A=0; //Azzeramento Registro
TCCR1B=0; //Azzeramento Registro
TCCR1A |= (1 << WGM11); // Setto la modalità Fast PWM a risoluzione variabile
TCCR1B |= (1 << WGM12) | (1 << WGM13);
TCCR1A |= (1 << COM1A1) | (1 << COM1B1); // Imposto le uscite 9 e 10 come non invertenti
TCCR1B |= (1 << CS10); // Imposto il Prescaler a 1
TIMSK1 |= (1 << TOIE1); // Abilito ISR su OverFlow
sei();
}

void loop() {
}


ISR (TIMER1_OVF_vect){

if ((Indice < 1) || (Indice == 250) || (Indice > 499)) { // Indice 0, 250 o 500 (Valore 0, incrocio delle semionde)
OCR1A = 0;
OCR1B = 0;
}

if ((Indice > 0) && (Indice < 250)) { // Indice compreso tra 1 e 249 (Valori tra 5..400..5)
OCR1A = onda[Indice];
}

if ((Indice > 250) && (Indice < 500)) { // Indice compreso tra 1 e 249 (Valori tra 5..400..5)
OCR1B = onda[Indice-250];
}

if (Indice > 499) { // Se l'indice è = 500 lo resetto per ricominciare il ciclo
Indice = 1;
}

else{
Indice++; // Incremento l'Indice
}
}

----------------------------------------------------------------------------------------------------------------------------------

 

ElettroshockNow

Avatar
GigaWatt


Gruppo:Utente
Messaggi:4656

Stato:



Inviato il: 31/03/2015 03:58:17

Aggiungo una piccola brutta notizia ...

Provate a collegare due led sui pin 9 e 10 e per vedere le due variazioni di luminosità e aggiungete nel setup:

TCCR1B |= (1 << CS12);//Imposta il prescaler a 1024 per i test


... ci sarà una sorpresa ... i led non sono mai spenti completamente
Notte notte

 

inverter90

Avatar
MegaWatt


Gruppo:Utente
Messaggi:323

Stato:



Inviato il: 31/03/2015 06:37:53


CITAZIONE

ICR1 = 640; // Setto il periodo a 40 µS (con Fck 16,0 Mhz, Prescaler 1)


scusami BellaEli, ma sta cosa no mi è chiara io pensavo diversamente.
Icr1 che funzione ha? E 640 con quale formula lo ricavi?



---------------
Il niente è impossibile finchè non ci provi!!!

 

inverter90

Avatar
MegaWatt


Gruppo:Utente
Messaggi:323

Stato:



Inviato il: 31/03/2015 08:25:39


CITAZIONE

ci sarà una sorpresa ... i led non sono mai spenti completamente
Notte notte


Elettro, ma come mai?Anche con fast pwm 10bit il led non si spegne del tutto.Anche mettendo gli OCRXX=0; rimane leggermente acceso. Invece ho provato modalità phase correct 9bit e si spegne con ocrxx= 0 è tutto spento..C'e una spiegazione per questo?



---------------
Il niente è impossibile finchè non ci provi!!!

 
 InizioPagina
 

Pagine: (167)  < ...  86   87   88   89   90   91   92   93   94   95   [96]   97   98   99   100   101   102   103   104   105   106  ...>    (Ultimo Msg)

Versione Mobile!

Home page       TOP100-SOLAR      Home page forum