Obiettivo: sfruttare le potenzialità di Del phi per simulare il funzionamento nel tempo delle principale reti elettriche.
Occorre
·
Stringgrid per raccogliere i dati della simulazione:
La prima colonna deve contenere l’andamento del tempo, le restanti colonne
conterranno le eventuali variabili dipendenti dal tempo da controllare che
normalmente sono:
o La tensione di ingresso del circuito Vi(t)
o La tensione di uscita del circuito Vu(t)
· Una oggetto Image dove tracciare il grafico
|
|
|
procedure TForm1.Button1Click(Sender: TObject);
var
Vi,Vu:real; //valori di ingresso e di uscita
r:integer;
t:real; //tempo di simulazione, viene incrementato di dt ogni giro
nc:integer; //durata simulazione in campioni
dt:real; //intervallo di tempo tra campioni
begin
t:=0;
dt:=0.000001;
nc:=1000;
with StringGrid1 do
begin
RowCount:=nc+1;
for r:=1 to RowCount-1 do
begin
Vi:=Quadra(t,nc*dt,10,0); //Funzione che riproduce la forma d’onda
Vu:=Partitore(Vi); //Funzione che simula il circuito
Cells[0,r]:=Format('%7.4g',[t]);
Cells[1,r]:=Format('%7.4g',[Vi]);
Cells[2,r]:=Format('%7.4g',[Vu]);
t:=t+dt;
end;
end;
Grafico(StringGrid1,Image1); //Funziona che grafica i valori cont. nella Stringrid1.
end;
Funzione di simulazione
function Partitore(Vi:real):real;
const
R1:real=500;
R2:real=500;
begin
result:=Vi*R2/(R1+R2);
end;
Funzione di generazione di forme d’onda
Parametri:
t: tempo in secondi
Per: Periodo in secondi
Amp: Ampiezza (Valore Massimo) in Volt
Offset:
|
function Quadra(t,Per,Amp,Offset:real):real; begin if frac(t/Per)>0.5 then result:=-Amp+Offset else result:=Amp+Offset; end;
|
function Triangolare(t,Per,Amp,Offset:real):real; var f:real; begin f:=frac(t/Per); if f>0.5 then result:=-Amp+(1-f)*Amp*4+Offset else result:=-Amp+f*Amp*4+Offset; end; |
|
function DenteSega(t,Per,Amp,Offset:real):real; begin result:=-Amp+frac(t/Per)*Amp*2; end;
|
Fase: sfasamento in radianti. function Sinusoide(t,Per,Amp,Offset,Fase:real):real; begin result:=Offset+Amp*sin(2*pi/Per*t+Fase); end; |
Esercitazioni:
1. Effettuare la simulazione con onda quadra come nell’esempio riportato.
2. Effettuare la simulazione con onda quadra a frequenza doppia.
3. Effettuare la simulazione con onda quadra a frequenza doppia onda solo positiva ampiezza 1V.
4. Effettuare la simulazione con onda triangolare a 1Khz
5. Effettuare la simulazione con onda dente di sega a 2Khz
6. Effettuare la simulazione con onda sinusoidale a 3Khz
7. Effettuare la simulazione con onda sinusoidale a 3Khz solo positiva
8. Con un onda a piacere abbassare il numero dei campione e valutare cosa succede.
//==============================================================================
// Grafico
//==============================================================================
procedure TForm1.Grafico(S:TStringGrid;I:TImage);
const
ytxtfmt='%5.2g';
xtxtfmt='%5.2g';
ColoreSf=clWhite;
ColoriY:array[1..4] of TColor=(clBlue,clRed,clGreen,clFuchsia);
MgSx =30;
MgDx =50;
MgSu =20;
MgGiu=35;
DivR =8;
DivC =10;
StepLeg=20;
var
MinX,MaxX:real;
MinY,MaxY:real;
MinY1,MaxY1:real;
MinY2,MaxY2:real;
n,m,x,y:integer;
dqy,dqx:integer;
kx,ky:real;
st:string;
function ElabMin(C:integer):real;
var
r:integer;
v:real;
begin
with S do
begin
result:=StrToFloat(Cells[C,1]);
for r:=2 to RowCount-1 do
begin
v:=StrToFloat(Cells[C,r]);
if v<result then
result:=v;
end;
end;
end;
function ElabMax(C:integer):real;
var
r:integer;
v:real;
begin
with S do
begin
result:=StrToFloat(Cells[C,1]);
for r:=2 to RowCount-1 do
begin
v:=StrToFloat(Cells[C,r]);
if v>result then
result:=v;
end;
end;
end;
begin
//Cancella grafico
I.Canvas.Brush.Color:=ColoreSf;
I.Canvas.Pen.Style:=psSolid;
I.Canvas.Pen.Color:=ClBlack;
I.Canvas.Rectangle(0,0,I.Width,I.Height);
//Elabora massimi e minini
MinX :=ElabMin(0);
MaxX :=ElabMax(0);
MinY :=ElabMin(1);
MaxY :=ElabMax(1);
for n:=2 to S.ColCount-1 do
begin
MinY1:=ElabMin(n);
if MinY>MinY1 then
MinY:=MinY1;
MaxY1:=ElabMax(n);
if MaxY<MaxY1 then
MaxY:=MaxY1
end;
//Disegna Reticolo
dqy:= (I.Height-MgSu-MgGiu) div DivR;
dqx:= (I.Width -MgSx-MgDx) div DivC;
ky:=dqy*DivR/(MaxY-MinY);
kx:=dqx*DivC/(MaxX-MinX);
I.Canvas.Pen.Style:=psDot;
I.Canvas.Pen.Color:=ClGray;
//Righe
for n:=0 to DivR do
begin
with I.Canvas do
begin
MoveTo(MgSx,I.Height-MgGiu-(n*dqy));
LineTo(MgSx+(DivC*dqx),I.Height-MgGiu-(n*dqy));
st:=Format(ytxtfmt,[MinY+(MaxY-MinY)*n/DivR]);
TextOut(MgSx-TextWidth(st)-2,I.Height-MgGiu-(n*dqy)-TextHeight(st) div 2-2,st);
end;
end;
//Colonne
for n:=0 to DivC do
begin
with I.Canvas do
begin
MoveTo(MgSx+(n*dqx),I.Height-MgGiu);
LineTo(MgSx+(n*dqx),I.Height-MgGiu-(DivR*dqy));
st:=Format(ytxtfmt,[MinX+(MaxX-MinX)*n/DivC]);
TextOut(MgSx+(n*dqx)-TextWidth(st) div 2,I.Height-MgGiu+4,st);
end;
end;
//Asse X
I.Canvas.TextOut(MgSx+(I.Width-MgSx-MgDx) div 2-I.Canvas.TextWidth(S.Cells[0,0]) div 2,
I.Height-I.Canvas.TextHeight(S.Cells[0,0])-2,
S.Cells[0,0]);
//Legenda
y:=MgSu+(I.Height-MgSu-MgGiu) div 2 - (S.ColCount-1) * StepLeg div 2;
x:=I.Width-MgDx+5;
I.Canvas.Pen.Style:=psSolid;
for n:=1 to S.ColCount-1 do
begin
with I.Canvas do
begin
Pen.Color:=clBlack;
TextOut(x,y+(n-1)*StepLeg,S.Cells[n,0]);
Pen.Color:=ColoriY[n];
MoveTo(x,y+(n-1)*StepLeg+TextHeight(S.Cells[n,0])+2);
LineTo(x+TextWidth(S.Cells[n,0]),y+(n-1)*StepLeg+TextHeight(S.Cells[n,0])+2);
end;
end;
I.Canvas.Pen.Color:=clBlack;
//Grafica
with I.Canvas do
begin
for n:=2 to S.RowCount-1 do
begin
for m:=1 to S.ColCount-1 do
begin
Pen.Color:=ColoriY[m];
MoveTo(MgSx+round((StrToFloat(S.Cells[0,n-1])-MinX)*kx),I.Height-MgGiu-round((StrToFloat(S.Cells[m,n-1])-MinY)*ky));
LineTo(MgSx+round((StrToFloat(S.Cells[0,n])-MinX)*kx),I.Height-MgGiu-round((StrToFloat(S.Cells[m,n])-MinY)*ky));
end;
end;
end;
end;