pascalio - Input-/Output-Bibliothek für Free Pascal

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Mathias »

Hast du diesen Link mal angeguckt.

http://wiki.freepascal.org/Lazarus_on_R ... zeduren.29

Vielleicht hilft dir dies weiter.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Warf »

Murphy. hat geschrieben:Hi,

ich beschäftige mich seit kurzem mit dem Raspberry Pi + Lazarus und habe eine Frage zu PascalIO. Ich würde gerne mit einem GPIO Pin über einen Transistor ein Relai schalten. Das Relai soll bei Überschreitung der Maximaltemperatur an einem Sensor schalten. Mit der Unit fpgpio müsste das doch eigentlich funktionieren.

Ich habe bist jetzt folgendes probiert um GPIO 21 bzw. Pin 40 auf true zu setzen.

Code: Alles auswählen


Code: Alles auswählen

procedur TForm5.Timer1Timer(Sender: TObject);
    var
    gpio: TGpioLinuxPin,
    write: TGpioDirection;
    begin
    na := True;
    gpio := TGpioLinuxPin.Create(21);
    gpio.Direction := write;
    gpio.Value := true;
    gpio.Destroy;
    end





Wäre cool wenn mir jemand auf die Sprünge helfen könnte.



Ich kenne mich damit nicht so wirklich aus, allerdings ist write eine lokale Variable und damit ist der Wert Undefiniert. Diesen Wert weist du dann der Direction zu, daher kannst du nicht bestimmen was für einen wert Direction letztendlich bekommen wird

Murphy.
Beiträge: 20
Registriert: Fr 21. Okt 2016, 19:02

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Murphy. »

Den Link hab ich mir schonmal angeguckt und es auch nachdem Beispiel ausprobiert.

Code: Alles auswählen

 
procedure TForm5.Timer1Timer(Sender: TObject);
var
pin_21: TGpioPin;
begin
na := True;
pin_21 := TGpioLinuxPin.Create(21);
pin_21.Direction := gdOut;
pin_21.Value := na;
Pin_21.Destroy;
end;
 


Das funktioniert aber auch nicht ???

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Socke »

Murphy. hat geschrieben:Hi,

ich beschäftige mich seit kurzem mit dem Raspberry Pi + Lazarus und habe eine Frage zu PascalIO. Ich würde gerne mit einem GPIO Pin über einen Transistor ein Relai schalten. Das Relai soll bei Überschreitung der Maximaltemperatur an einem Sensor schalten. Mit der Unit fpgpio müsste das doch eigentlich funktionieren.

Ich habe bist jetzt folgendes probiert um GPIO 21 bzw. Pin 40 auf true zu setzen.

PascalIO gibt die Pin-Nummern direkt an Linux weiter; Daher ist 21 für den Hardware-Pin 40 schon richtig.

Bitte prüfe nach dem Aufruf von pin_21.Value := True, ob die gesetzen Werte mit den Dateien unter /sys/class/gpio/ übereinstimmen. Mit Aufruf des Destruktors wird der GPIO-Pin wieder zur Verwaltung an den Kernel zurückgegeben und damit möglicherweise wieder auf den Standard zurückgesetzt; daher wäre es besser zu Beginn des Programms eine Instanz des TGPIOLinuxPins zu erstellen und erst am Ende des Programms wieder freizugeben.

Natürlich darf der Pin 21 nicht durch andere Funktionen wie SPI genutzt werden. Hier ist ggf. nicht die aktuelle Nutzung ausschlaggebend sondern ob die jeweilgen Kernel-Module geladen sind.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Murphy.
Beiträge: 20
Registriert: Fr 21. Okt 2016, 19:02

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Murphy. »

Hi,

der Pin 21 wird von den SPI-Geräten nicht benutzt. Ich habe mir jetzt erstmal einen einzelnen Form mit zwei buttons und einem timer nur zum testen erstellt.
Der Code sieht so aus:

Code: Alles auswählen

unit u_notaus_form;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  StdCtrls, fpgpio;
 
var
  na: Boolean;
  pin_21: TGpioPin;
 
type
 
  { TForm5 }
 
  TForm5 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
 
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form5: TForm5;
 
implementation
 
{$R *.lfm}
 
{ TForm5 }
 
procedure TForm5.Timer1Timer(Sender: TObject);
begin
  pin_21.Value := na;
end;
 
procedure TForm5.Button1Click(Sender: TObject);
begin
  na := true;
end;
 
procedure TForm5.Button2Click(Sender: TObject);
begin
  na := false;
end;
 
procedure TForm5.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  pin_21.Destroy;
end;
 
procedure TForm5.FormCreate(Sender: TObject);
begin
  pin_21 := TGpioLinuxPin.Create(21);
  pin_21.Direction:= gdOut;
end;
 
end.


In dem Verzeichnis /sys/class/gpio/ tut sich nichts. Ich habe es so verstanden, dass dort eigentlich über Create eine Datei für Pin21 erzeugt werden soll. Löscht der Destructor die ganze Datei, oder wie kann ich das verstehen?

Liegts am Code? Was mach ich falsch?

Über das Terminal kann ich den Pin auf True bzw False setzen.

Danke für die Tipps! :)

Murphy.
Beiträge: 20
Registriert: Fr 21. Okt 2016, 19:02

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Murphy. »

Hat sich erledigt, es läuft !:)

ATILIUS_REGULUS
Beiträge: 57
Registriert: Mi 20. Feb 2013, 10:06
OS, Lazarus, FPC: KUBUNTU 14.04 (fpc 3.3.1) / Raspbian (fpc 3.3.1)
CPU-Target: x86, x64, ARM
Kontaktdaten:

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von ATILIUS_REGULUS »

Bin nicht sicher, ob ich ein neues Thema starten sollte, aber da dieses Thema ohnehin über mehrere Jahre ging, füge ich es hier ein.

Habe ein paar Probleme mit pascalio unter Raspberry festgestellt, welche ich kurz darlegen möchte:
Mein System: fpc V3.3.1, Raspberry Pi 3B

Hierzu habe ich kleines Testprogramm geschrieben, welches die Punkte verdeutlicht:

Code: Alles auswählen

program test_fpgio;
 
{$mode objfpc}{$H+}
 
uses
  baseunix,
  fpgpio;
 
var
  GPIO : TGpioLinuxPin;
  New_Value : Boolean;
 
begin
  GPIO := TGpioLinuxPin.Create (25);
  GPIO.Direction := gdIn;
  GPIO.InterruptMode := [gimRising];
 
  WriteLn ('Startig WaitForInterrupt...');
 
  GPIO.WaitForInterrupt (TGpioLinuxPin.INTERRUPT_WAIT_INFINITE, New_Value);
 
  WriteLn ('WaitForInterrupt finished.');
 
  GPIO.Destroy;
end.
 

1. Problem: "class function GetCount: Longword; static; virtual; abstract;"

Kompilieren des Programms liefert eine Fehlermeldung:

Code: Alles auswählen

fpgpio.pas(123,48) Error: Procedure directive "VIRTUAL" cannot be used with "STATIC"
fpgpio.pas(123,65) Error: Only virtual methods can be abstract
fpgpio.pas(226,1) Fatal: There were 2 errors compiling module, stopping
Fatal: Compilation aborted

Das Problem sind die Class Function in Zeile 123 und das Class Property in Zeile 136 der Datei fpgpio.pas. Wenn man diese beiden Zeilen auskommentiert, kompiliert das Programm.


Wesentlich interesanter ist jedoch der zweite Punkt:

2. Problem: "Nicht freigegebene Betriebsmittel"

Wenn man die beiden oben aufgeführten Zeilen in fpgpio.pas auskommentiert hat, kompiliert und läuft das Programm.
Allerdings läuft es nur jedes zweite Mal, jedes andere zweite mal kommt beim Aufruf von
GPIO.WaitForInterrupt (TGpioLinuxPin.INTERRUPT_WAIT_INFINITE, New_Value);
die Meldung:

Code: Alles auswählen

An unhandled exception occurred at $00044614:
EInterruptError: No interrupt mode set.
  $00044614
  $00010228

Offensichtlich werden beim Aufruf von GPIO.Destroy nicht alle Betriebsmittel freigeben. Vermutlich ist eine Datei noch geöffnet oder gesperrt, oder hat einen Inhalt, welcher zu dem Fehler führt. Interessant ist, daß der Fehler bei jedem zweiten Start nicht vorhanden ist, also wird das Problem eventuell durch Aufruf der Exception beseitigt.
Mit Hilfe des Debuggers habe ich herausgefunden, daß das Problem darin besteht, daß trotz Aufruf von "GPIO.InterruptMode := [gimRising];" InterruptMode danach immer noch leer ([]) ist.
Habe schon alles mögliche vor den Destroy und auch nach dem Create versucht (Mehrere Objekte von TGpioLinuxPin erzeugt und freigegeben, InterruptMode mehrfach gesetzt und vor destroy auf [] gesetzt), aber nichts hat funktioniert.
Am sinnvollsten wäre es, das betroffene Betriebsmittel in Destructor wieder freizugeben beziehungsweise zurückzusetzen, die Frage ist nur, wie genau.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Socke »

ATILIUS_REGULUS hat geschrieben:Das Problem sind die Class Function in Zeile 123 und das Class Property in Zeile 136 der Datei fpgpio.pas. Wenn man diese beiden Zeilen auskommentiert, kompiliert das Programm.

Ursache ist eine Änderung nach FPC 3.2, der die Syntax strenger prüft; der akutellste Commit behebt den Fehler auch an anderer Stelle.

ATILIUS_REGULUS hat geschrieben:2. Problem: "Nicht freigegebene Betriebsmittel"

Beim Destroy wird der GPIO-Pin wieder "unexportiert", d.h. steht danach nicht mehr über sysfs zur Verfügung. Inwiefern durch den Linux GPIO-Treiber der Pin in irgendeinen Zustand (zurück-)versetzt wird, liegen mir keine Informationen vor - ich gehe mal von "gar nicht" aus. Damit könnten einige Einstellungen von vorherigen Programmläufen noch existieren.

Eine Frage habe ich noch, da ich das nicht nachvollziehen kann. Du schreibst Mit Hilfe des Debuggers habe ich herausgefunden, daß das Problem darin besteht, daß trotz Aufruf von "GPIO.InterruptMode := [gimRising];" InterruptMode danach immer noch leer ([]) ist.. Wie hast du das herausgefunden? Der Wert wird gar nicht im Programm gespeichert sondern direkt per sysfs an das Betriebssystem weitergegeben (und auch von dort gelesen). Per Debugger wäre das gar nicht auswertbar; ggf. kann man per Debugger das Programm anhalten und per Shell die Datei /sys/class/gpio/gpio25/edge auslesen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Timm Thaler »

Ohne jetzt in die fpgpio geschaut zu haben: Oft wird beim Anmelden der GPIOs der Fehler gemacht, gleich nach dem Enable die Dir zu setzen. Es kann aber bis zu 100msec (gemessen) dauern, bis ein GPIO enabled wird, wird vorher auf den GPIO geschrieben läuft das ins Leere und der GPIO ist zwar enabled, steht aber noch auf Eingang. Beim zweiten Versuch ist der GPIO dann bereits enabled und das Dir klappt, deswegen merken die Programmierer das oft nicht.

Genauso kann ein GPIO nicht freigegeben werden, wenn man ihn disbled und dann nicht wartet, sondern das Programm beendet.

Im einfachsten Fall mal ein paar Pausen einfügen. Wenn man es sauber machen will, fragt man nach einem Enable / Disable ab, ob das auch durchgeführt wurde.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Socke »

Timm Thaler hat geschrieben:Im einfachsten Fall mal ein paar Pausen einfügen. Wenn man es sauber machen will, fragt man nach einem Enable / Disable ab, ob das auch durchgeführt wurde.

Ich hatte auf Github hierzu eine Issue erhalten. Mit folgendem Code habe ich keine Probleme mehr. Hast du eine Idee, wie man das Warten auf ein Minimum reduzieren kann bzw. nicht einfach x ms wartet sondern feststellen kann, ob der Linux-Kernel bereits fertig ist?

Code: Alles auswählen

  input := TGpioLinuxPin.Create(25); // GPIO 25
  Sleep(100);
  input.Direction := gdIn;
  Sleep(100);
  input.InterruptMode := [gimRising, gimFalling]; // interrupt on open and close
  Sleep(100);
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Timm Thaler »

Ich frage dazu nach dem Create ab, ob der GPIO existiert. Sobald ich eine positive Rückmeldung bekomme, kann ich weitermachen, dauert meist um die 25-50msec, manchmal bis 100msec, pro GPIO. Ansonsten nach Timeout Fehlermeldung.

Allerdings arbeite ich auch mit Dateizugriffen und ohne PWM / Interrupt.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Socke »

Timm Thaler hat geschrieben:Ich frage dazu nach dem Create ab, ob der GPIO existiert. Sobald ich eine positive Rückmeldung bekomme, kann ich weitermachen, dauert meist um die 25-50msec, manchmal bis 100msec, pro GPIO. Ansonsten nach Timeout Fehlermeldung.

Kannst du mir hierzu ein kleines Code-Beispiel bereitstellen, das ich übernehmen darf?

Timm Thaler hat geschrieben:Allerdings arbeite ich auch mit Dateizugriffen und ohne PWM / Interrupt.

Die "Interrupts" sind hier auch nur Dateizugriffe; eigentlich wartet das Programm nur darauf, dass sich der Dateiinhalt ändert. PWM ist hier noch gar nicht im Spiel, da das eigene sysfs-Verzeichnisse wären (nur geht hier im Forum die Diskussion ein wenig quer durch die Threads).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

ATILIUS_REGULUS
Beiträge: 57
Registriert: Mi 20. Feb 2013, 10:06
OS, Lazarus, FPC: KUBUNTU 14.04 (fpc 3.3.1) / Raspbian (fpc 3.3.1)
CPU-Target: x86, x64, ARM
Kontaktdaten:

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von ATILIUS_REGULUS »

Danke für die raschen Antworten.

Was den Debugger betrifft, bin ich in der IDE mit dem Debugger die einzelen Schritte durchgegeangen, und habe gesehen, daß die Exception in Zeile 616 von fpgpio auftritt, obgleich ich InterruptMode direkt zuvor auf [gimRising] gesetzt hatte:

Code: Alles auswählen

  // interrupt can't be done without a mode set prior
  if InterruptMode = [] then
    raise EInterruptError.Create(sInterruptModeNotSet);
 


Aufgrund Eurer Hinweise habe ich mir alle Zuweisungen nochmals angesehen und mehrere Sachen geprüft:
- Es reicht nicht, zu warten, bis das Verzeichnis /sys/class/gpio/gpio25 erstellt wurde. Der Fehler tritt nach dem Anlegen immer noch auf.
- Sowohl das Anlegen des Verzeichnisses in Create als auch das Setzen von Direction in "TGpioLinuxPin.SetDirection(AValue: TGpioDirection);" werden praktisch unmittelbar durchgeführt, siehe Beispielprogramm 1 unten.
- Das Problem ist das Setzen des Interruptmode durch die Datei edge, hierzu werden im Beispielprogramm 1 zwischen 300 und 500 Durchläufe benötigt.


Beispielprogramm 1:

Code: Alles auswählen

program test_fpgio;
 
{$mode objfpc}{$H+}
 
uses
  baseunix,
  fpgpio,
  SysUtils;
 
Const
  GPIO_LINUX_BASE_DIR = '/sys/class/gpio/';
  GPIO_LINUX_GPIOPIN_DIR = GPIO_LINUX_BASE_DIR + 'gpio%d/';
  EXPORT_FILE = GPIO_LINUX_BASE_DIR+'export';
  UNEXPORT_FILE = GPIO_LINUX_BASE_DIR+'unexport';
  PinID = 25;
 
var
  s: String;
  GPIO : TGpioLinuxPin;
  New_Value : Boolean;
  I : Integer;
 
begin
  GPIO := TGpioLinuxPin.Create (PinID);
 
  I := 0;
  Repeat
    s := Format (GPIO_LINUX_GPIOPIN_DIR, [PinID]);
    WriteLn ('Waiting Create ', I);
    Inc (I);
  until DirectoryExists (s) = TRUE;
 
  I := 0;
  Repeat
    GPIO.Direction := gdIn;
    WriteLn ('Waiting CREATE gdIn ', I);
    Inc (I);
  until GPIO.Direction = gdIn;
 
  I := 0;
  Repeat
    GPIO.InterruptMode := [gimRising];
    WriteLn ('Waiting gdRising ', I);
    Inc (I);
  until GPIO.InterruptMode = [gimRising];
 
 
  WriteLn ('Startig WaitForInterrupt...');
  For I := 0 to 3 do
    Begin { For }
      GPIO.WaitForInterrupt (TGpioLinuxPin.INTERRUPT_WAIT_INFINITE, New_Value);
      WriteLn ('WaitForInterrupt : ', I);
    End; { For }
  WriteLn ('WaitForInterrupt finished.');
 
  GPIO.Destroy;
end.




Die beste Lösung aus meiner Sicht ist eine Überprüfung des Edge-Zustandes innerhalb der Procedure SetInterruptMode, dann ist der Programmablauf wie erwartet sequentiel und die Nebenläufigkeit behoben:

Code: Alles auswählen

procedure TGpioLinuxPin.SetInterruptMode(AValue: TGpioInterruptMode);
Const
  TIMEOUT_INTERRUPTMODE_MS = 100;
 
Var
  f, s: String;
  I : Integer;
 
begin
  f := Format(GPIO_LINUX_GPIOPIN_DIR+'edge', [PinID]);
  s := GetEdgeString(AValue);
 
  I := 0;
  Repeat
    WriteToFile(f, s);
    Sleep (1);
    Inc (I);
  until (InterruptMode = AValue) OR (I > TIMEOUT_INTERRUPTMODE_MS);
 
  If I > TIMEOUT_INTERRUPTMODE_MS then
    Begin { then }
      Raise EInvalidEgde.CreateFmt('Timeout in SetInterruptMode : %s', [s]);
    End; { then }
end;
 


Damit läuft das Beispielprogramm 2 wie erwartet jedesmal ohne Fehler:

Beispielprogramm 2:

Code: Alles auswählen

program test_fpgio;
 
{$mode objfpc}{$H+}
 
uses
  baseunix,
  fpgpio,
  SysUtils;
 
Const
  PinID = 25;
 
var
  GPIO : TGpioLinuxPin;
  New_Value : Boolean;
  I : Integer;
 
begin
  GPIO := TGpioLinuxPin.Create (PinID);
  GPIO.Direction := gdIn;
  GPIO.InterruptMode := [gimRising];
 
  WriteLn ('Startig WaitForInterrupt...');
  For I := 0 to 3 do
  Begin { For }
    GPIO.WaitForInterrupt (TGpioLinuxPin.INTERRUPT_WAIT_INFINITE, New_Value);
    WriteLn ('WaitForInterrupt : ', I);
  End; { For }
  WriteLn ('WaitForInterrupt finished.');
 
  GPIO.Destroy;
end.




Vielleicht könnt Ihr die Procedure TGpioLinuxPin.SetInterruptMode ja entsprechend ergänzen.
Wenn man ganz auf Nummer Sicher gehen möchte, kann man in die anderen Set Proceduren und in Create ebenfalls eine solche Überprüfung einbauen, war bei mir aber nicht notwendig.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Socke »

ATILIUS_REGULUS hat geschrieben:Vielleicht könnt Ihr die Procedure TGpioLinuxPin.SetInterruptMode ja entsprechend ergänzen.
Wenn man ganz auf Nummer Sicher gehen möchte, kann man in die anderen Set Proceduren und in Create ebenfalls eine solche Überprüfung einbauen, war bei mir aber nicht notwendig.

Vielen Dank für den Vorschlag; Ich denke, es sollte dann bei allen ergänzt werden. In diesem Fall ist das kein Problem, da die GPIO per Default auf Input stehen
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: pascalio - Input-/Output-Bibliothek für Free Pascal

Beitrag von Timm Thaler »

Socke hat geschrieben:Kannst du mir hierzu ein kleines Code-Beispiel bereitstellen, das ich übernehmen darf?


In Anlehnung an das Beispiel im Tutorial hab ich mal das gemacht:

Code: Alles auswählen

function Tgpio.PinEnable(apin : string) : integer;
var
  fhnd, kd : integer;
  fname : string;
begin
  try
    fhnd := FpOpen(cgpio_exp, O_WrOnly);   // Export Pin
    FpWrite(fhnd, apin[1], Length(apin));   // Export Pin Nummer
  finally
    FpClose(fhnd);
  end;
  if fhnd > 0 then begin  // wenn Open erfolgreich
    fname := cgpio_pin + apin + cgpio_dir;   // Direction Pin prüfen
    for kd := 1 to 20 do begin  // warten auf Write fertig
      try
        fhnd := FpOpen(fname, O_WrOnly);   // prüfen auf fertig
      finally
        FpClose(fhnd);
      end;
      if fhnd > 0 then begin   // wenn Open erfolgreich, raus
        break;
      end;
      Sleep(5)// maximal 20 x 5 msec
    end;
  end;
  result := fhnd;
end;


Damals war ich aber noch ziemlich frisch in Freepascal, statt Fpopen hätte man auch FileExists nehmen können, weiss müsste mal probieren was die bessere Performance hat. Wichtig ist die Abbruchbedingung, sonst hängt sich der Kram schlimmstenfalls ganz auf, wenn man einen falschen GPIO angibt.

ATILIUS_REGULUS hat geschrieben:Sowohl das Anlegen des Verzeichnisses in Create ... werden praktisch unmittelbar durchgeführt, siehe Beispielprogramm 1 unten.


Das scheint Dir so, weil das Programm abstürzt, der GPIO damit nicht mehr disabled und damit noch vom vorherigen Programmlauf enabled ist.

Antworten