Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Relaisplatine über COM Port ansteuern (https://www.delphipraxis.net/1076-relaisplatine-ueber-com-port-ansteuern.html)

Salomon 15. Okt 2002 08:40


Relaisplatine über COM Port ansteuern
 
Hallo,
in versuche seit geraumer Zeit die 8 Fach Relaisplatine von Conrad anzusteuern. Leider nur mit mäßigen Erfolg. Die Platine wird an die Serielle Schnittstelle angeschlossen.
Ein Hardware Fehler kann ausgeschlossen werden, da sie mit der (selbstprogrammierten)Software von jemand anderem funktioniert.

Die Serielle Schnittstelle habe ich erfolgreich initialisiert. Siehe Code:

Code:
function opencom(comport : string): boolean;
begin
  hport:= CreateFile(PChar(comport),GENERIC_READ + GENERIC_WRITE,0,nil,OPEN_EXISTING,0,0);

  GetCommState(hport,dcb);

  dcb.BaudRate := StrToCard(comconfig.baudrate.Text);// Bautrate
  dcb.ByteSize := StrToInt(comconfig.data.Text);    // 8 Bits je Byte
  dcb.Parity  := StrToInt(comconfig.parity.Text);  // kein Paritäts Bit NOPARITY
  dcb.StopBits := StrToInt(comconfig.stopbit.text); // ein Stopp Bit ONESTOPBIT
  dcb.wReserved:= 0;
                         // In Buffer                       // Out Buffer
  if SetupComm(hPort, strtoint(comconfig.inbuffer.Text), strtoint(comconfig.Data.Text))
     then
      begin
       result := true;
       log(comconfig.ComboBox1.Text + 'erfolgreich initialisiert...');
      end
     else
      begin
       result := false;
       log(comconfig.ComboBox1.Text + 'konnte NICHT initialisiert!');
      end;

  SetCommState(hport,dcb);
end;
Daten sende ich über diese Funktion an die Karte:

Code:
                        //  byte
procedure outport(data: char);
var
  len: cardinal;
  written: dword;  // cardinal
begin
  len:= 1;
  WriteFile(hport,data,len,written,nil);
end;

Mein Problem liegt nun im ansteuern der Relais! Die Karte erwartet einen 4 Byte langen Befehlsrahmen (siehe weiter unten Datenblatt), den ich wahrscheinlich nicht richtig "aufbaue" und an die Karte sende.

Auch das initialisieren der Karte klappt nicht!.

Code:
procedure senddata(par1, par2,par3: byte);
var summe : byte;
begin
summe := par1 xor par2 xor par3;
outport(chr(par1));
outport(chr(par2));
outport(chr(par3));
outport(chr(summe));
end;

Procedure initcard;
begin
senddata (1,1,0);
end;
Auf Seite 7 des Datenblattes steht wie die Relais anzusteuern sind.
Auf der darauf folgenden Seite ist ein BASIC Programm, das mich leider nicht weiterbringt. Datenblatt


So, ich hoffe das war nicht zuviel auf einmal :-) Please help.

Mfg
Salomon

jbg 15. Okt 2002 09:50

Liste der Anhänge anzeigen (Anzahl: 1)
Da hast du Glück. Ich habe da eine Unit für genau diese Relaiskarte.
Im Attachment findest du die gepackte Unit.

Salomon 15. Okt 2002 10:28

Super, das sieht echt gut aus :-)

Ich werde mir das gleich mal genauer anschauen.

Salomon 15. Okt 2002 12:26

Mit der Unit komme ich genauso weit wie vorher, es hapert einfach an den Daten, die ich zum Schalten der Relais an die Karte senden muss.

Die Function rel.CmdSetPorts(1,1); erledigt das für mich. Wobei der zweite Parameter vom Typ Byte ist und daher aus 8 Bit besteht.

In der Anleitung steht dazu folgendes:
Ports setzten und lesen lassen, Bit 0 im Datenwert korrespondiert mit Relais 1, Bit 1 entsprechend mit Relais 2.


Wie es aussieht muss ich die 8 Bits des Bytes einzeln setzen können, also 0 oder 1, wie geht das?

Mfg
Salomon

wwerner 15. Okt 2002 13:31

DeinByte := 0; //init
DeinByte := DeinByte or (1 shl 3) //setzt das 3 bit in DeinByte

sakura 15. Okt 2002 13:50

Wenn Du nur ein Relay (z.B. das 6., also Bit 5) ändern möchtest, dann musst Du zuerst den aktuellen Status ermitteln (COM auslesen), dann das entsprechende Bit setzen und anschliessend wieder die Daten zum COM Port schreiben.

Code:
//Pseudo Code

procedure SetRelay(RelayBit: Byte; SwitchOn: Boolean);
var
  CurrState: Byte;
begin
  CurrState := ReadByteFromCOM;
[color=#0800ff] if SwitchOn then
    CurrState := CurrState or (1 shl RelayBit)
  else
    CurrState := CurrState and (not (1 shl RelayBit));[/color]
  WriteByteToCOM(CurrState);
end;


//// später im Code

// setze Relais 6 on
SetRelay(5, True);

// setze Relais 6 off
SetRelay(5, False);
Der farbige Bereich ist der eigentliche Teil zum Schalten eines Relais. Bedenke, das mit dem Schreiben eines Bytes immer acht Relais geschalten werden.

Salomon 15. Okt 2002 20:06

So, das Schalten der einzelenen Relais funktioniert dank euch schonmal.

Wenns noch irgendwelche Probleme gibt melde ich mich hier.

Thanx
Salomon

jbg 15. Okt 2002 21:32

Zitat:

Zitat von Salomon
Die Function rel.CmdSetPorts(1,1); erledigt das für mich.

Warum nutzt du denn die Lowlevel-Funktionen von TRelais? Mit den als High-Level kommentierten Methoden kannst du auch sakuras Code ganz einfach in einer einzigen Zeile abhandeln:. ActivatePorts(1, 1 shl BitNum) bzw. DeactivatePorts(1, 1 shl BitNum) oder wenn du die Ports von an nach aus bzw. von aus nach an schalten willst: TogglePorts(1, 1 shl BitNum)

Salomon 16. Okt 2002 10:33

Du hast recht, vor lauter Hardware naher Programmierung habe ich wohl die Highlevel Functions ganz übersehen.

Eine Frage hätte ich noch. Mit welcher Funktion kann ich den Status der Relais abfragen?
Die Function müsste mir doch ein Byte zurückgeben, indem alle momentanen schaltzustände sind.

wwerner 16. Okt 2002 10:39

GetPorts

Salomon 16. Okt 2002 17:19

Ich habe gerade festgestellt, das die Highlevel Function ein Abfragen des momentanen Status überflüssig machen. Hier nun die Function zum schalten der Relais:

Code:
Procedure SwitchRelais (CardNr: Byte; RelaisNr: Byte; SwitchOn: Boolean);
var
  n: Byte;
begin
 n := 0;
 n := n or (1 shl RelaisNr);
  if SwitchOn then
      rel.ActivatePorts(CardNr,n)
  else rel.DeactivatePorts(CardNr,n);
end;

Procedure InvertOneRelais (CardNr : Byte; RelaisNr: Byte);
Var n : byte;
Begin
 n := 0;
 n := n or (1 shl RelaisNr);
 rel.TogglePorts(CardNr,n);
end;
Mfg
Salomon

TraxTerra 4. Jan 2005 19:25

Re: Relaisplatine über COM Port ansteuern
 
Kann mir einer Sagen ob sich die Karte auch unter XP ansteuern lässt ?
Wenn Jaein, was brach ich für einen Treiber.

Danke im Voraus.

Muetze1 5. Jan 2005 00:31

Re: Relaisplatine über COM Port ansteuern
 
Moin!

Das Ding hängt an einer Standard RS232C Schnittstellen (serielle Schnittstelle) und ist damit unabhängig vom Betriebssystem ansteuerbar. Es sollte keinen Unterschied zwischen Windows 95 und Windows XP geben. Selbst die WinAPI Funktionen für CommIO haben keine grossen Änderungen erfahren.

Ansonsten für die Bits nochmal ein kleiner Link für die anderen die es lesen und vielleicht fragen würden: Bitoperationen

MfG
Muetze1

TraxTerra 5. Jan 2005 19:25

Re: Relaisplatine über COM Port ansteuern
 
Danke für die schnelle Antwort.

Habe gefragt weil XP normalerweise keinen direkten Zugriff auf die Ports zulässt, ok hab da vieleicht was in den falschen Hals bekommen.

mfg
Ralf

Muetze1 6. Jan 2005 00:00

Re: Relaisplatine über COM Port ansteuern
 
Moin!

Naja, das ist richtig, aber ich bin davon ausgegangen das beim Zugriff auf den COM Port die von Windows angebotenen Communication Funktionen benutzt werden und keine DLL die sich hinterrücks Hardwarezugriff holt damit man Windows von hinten in den Rücken schiessen kann. Deshalb meine Antwort.

In diesem Beitrag steht mehr zu den Windows Communication Functions

MfG
Muetze1

TraxTerra 6. Jan 2005 18:58

Re: Relaisplatine über COM Port ansteuern
 
Sorry das ich nochmal nach Frage.
Es geht sich um die Unit die weiter oben zum download angeboten wird, brauch ich für die einen extra Porttreiber für XP oder funst das auch ohne schon ?

mfg
Ralf

Muetze1 6. Jan 2005 19:08

Re: Relaisplatine über COM Port ansteuern
 
Moin!

Zitat:

Zitat von TraxTerra
..., brauch ich für die einen extra Porttreiber für XP oder funst das auch ohne schon ?

Das funktioniert ohne Porttreiber auch unter XP, da die Unit ordentlich mit den WinAPI Comm Funktionen arbeitet.

MfG
Muetze1

TraxTerra 8. Jan 2005 13:26

Re: Relaisplatine über COM Port ansteuern
 
Uaaaaa... Kann mir mal einer verraten wie das mit dem GETPorts funktioniert ?

Ich bekomm immer False zurück, egal ob Port geschaltet oder nicht.
Mich wundert aber auch schon (besser da steig ich nicht ganz durch) warum ich bei
GetPorts den Port mit angeben muss obwohl der in der Funktion GetPorts gleich wieder auf 0
gesetzt wird. Was mach ich falsch.

Hier meine Function :

Delphi-Quellcode:
Function RelStatus (COM_Port : String; Karte_Nummer : Byte; Klemme : Byte) : Boolean;
var
  rel : TRelaisCard;
  n : Byte;
  Schalten : Boolean;
  begin
    Result := False;
    rel := TRelaisCard.Create;
    try

      rel.ComPort := COM_Port;
       if rel.Init > 0 then
          begin
          n := 0;
          n := n or (1 shl Klemme);

          Result := rel.GetPorts(Karte_Nummer,n);
        end;

  finally
    rel.Free;
  end;
end;
Hat einer mal einen Code Schnipsel für mich ?

mfg
Ralf

TraxTerra 8. Jan 2005 14:20

Re: Relaisplatine über COM Port ansteuern
 
Ich glaub ich hab die Antwort schon.
GetPorts kann nicht den aktuellen Schaltzustand abfragen nur ob ein Port exestiert oder nicht.
Wenn ich mir die Platine so anschaue geht das Technich garnicht.
Oder seh ich das Falsch ?

mfg
Ralf

Helmi 20. Dez 2005 16:29

Re: Relaisplatine über COM Port ansteuern
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich hab mir mal vor ein paar Jahren diese Relaiskarten zugelegt, dazu aber auch noch die Conrad-Win-Software.
Da ich diese Software aber nicht mehr habe (ich weiss nicht wo die geblieben ist), möcht ich selbst ein Programm
schreiben, um diese Karten anzusteuern.

Ich hab mir diese Unit runtergeladen, zum Ansteuern der Karten. Aber ich komme auf keinen grünen Zweig.

Anbei mal mein Testprogramm. Vielleicht kann mir ja jemand sagen, was ich verkehrt mache.

Vielen Dank im Vorraus!

:wink:

Helmi 21. Dez 2005 20:03

Re: Relaisplatine über COM Port ansteuern
 
*push* the Button :-)

weiss jemand was an meinem Code falsch ist?


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz