Simulazioni di circuiti elettrici con Delphi

Obiettivo: sfruttare le potenzialità di Del phi per simulare il funzionamento nel tempo delle principale reti elettriche. 

 

Scarica Programma (da casa)

Scarica Programma (da scuola)

 

Preparazione del’ambiente di lavoro:

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

 


Esempio di circuito da simulare.

 


     

 

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;