IOW immer noch probleme mit ReadImmediate

Dies ist das deutsche Forum für alle Themen um den IO-Warrior. Beiträge bitte nur in Deutsch.

Moderator: Guido Körber

Post Reply
robert.ferralux
Posts: 8
Joined: Wed Dec 06, 2006 4:36 pm
Location: Lkrs. Augsburg

IOW immer noch probleme mit ReadImmediate

Post by robert.ferralux »

Hallo liebe IOW-Gemeinde,
ich habe immer noch ein Problem mit meinem selbst gebauten Prüfgerät
rund um einen IOW40 mit Ansteuerung aus Delphi 6 raus.
Im Dezember habe ich schon mal dieses Problem hier vorgestellt:
http://www.codemercs.de/phpBB2/viewtopic.php?t=864
Das Prüfgerät testet kleine Relais (also Signalrelais und keine
Schütze) im Dauertest mit belasteten Kontakten.

Jetzt zum Problem:
----------------------
Meine Software steuert über einen Timer den Treiber für das
Relais an. Dieser Treiber schaltet das Relais zyklisch ein
und aus (2500msec =default). Gleichzeitig wird mit diesem
Timer eine zweiter Timer gestartet. Die Zeit betägt 500msec
(Defaultwert). Läuft dieser Timer ab, so liest ein Unterpro-
gramm die Ports des IOW zurück und wertet die Pegel von
den Relaiskontakten aus (eigentlich nur zwei Bits).

Zur Software:
----------------
Das Programm tut EIGENTLICH auch seinen Dienst. Nur ab und zu
werden die Werte vom Port nicht richtig zurückgelesen oder
der Port wird nicht gesetzt und somit stimmen die erwarteten
Werte nicht und ich bekomme sporadisch Relaisfehler.

Beim Schreiben übergebe ich 2 Bytes mit dem Ausgabebitmuster
an den Records und dann an die Routine IowKitWrite:
{*** Bitmuster an den Ausgängen Port 2&3 setzten ***}
Report.ReportID := 0;
Report.Bytes[2] := PortVal2; // Ausgang
Report.Bytes[3] := PortVal3; // Ausgang
IowKitWrite (IOWarriors[1], IOW_PIPE_IO_PINS, @Report, IOWKIT40_IO_REPORT_SIZE);

Da ich beim Einlesen den momentan Zustand der Ports benötige
wäre IOKitReadImmediate eigentlich der richte Ansatz da dieser
ja einen Befehl zum IOW sendet und dann das aktuelle Ergebniss
zurück gibt (oder irre ich da?)
Da ich damit aber auch Probleme habe verwende ich momentan
"IowKitReadNonBlocking". Nachdem ich ja was an den Port schreibe
und meine Hardware daraufhin was ändert, sollte ich ja den richtigen
Wert im Puffer haben und den zurücklesen.

IOWKitSetTimeOut (IOWarriors[1],1000);
ReadValid := IowKitReadNonBlocking (IOWarriors[1], IOW_PIPE_IO_PINS,@Report,IOWKIT40_IO_REPORT_SIZE) = 0;
TmpReport := Report;

Dieser Programmteil läuft sogar in einer Schleife bis "ReadVaild" oder "TimeOut"

Zur Hardware:
----------------
Es ist ein IOW40, der aus dem PC über USB versorgt wird. Alle
Leitungen VOM IOW weg gehen über einen 74HCT245 auf der IOW-
Platine dann auf eine eigene Platine mit einem ULN2003 der mein
zu testendes Relais treibt. Für das zu testensde Relais befindet
sich eine eigene Stromversorgung 5/12/24 Volt max. 1A im Prüfgerät.
Alle Signale VOM Prüfgerät ZUM IOW sind über Optokoppler getrennt
und der Kollektor mit Pull-Ups gegen die "USB-5V" des Optokopplers
steuert wiederum eine 74HCT245 auf der IOW Platine an. Dieser
zweite HCT245 treibt dann die Eingänge des IOW.
Die 245er sind mit den 5V aus dem IOW versorgt wobei diese 5V
nochmal über eine Drossel entkoppelt sind und die 5V an jedem
IC nochmal mit 100n abgeblockt.


F R A G E :
=======
Hat jemand eine Idee wo ich noch suchen kann oder wo mein Programm verändert
werden muß, damit ich stabile Ergebnisse vom IOW zurückbekomme.

Bei der Entwicklung hatte ich schon ein Problem beim Zugriff
auf den IOW: http://www.codemercs.de/phpBB2/viewtopic.php?t=844
Robert Marquardt
Posts: 543
Joined: Mon Dec 01, 2003 6:09 pm

Post by Robert Marquardt »

Der einfachste Ansatz ist statt IowKitReadImmediate einfach die Special Mode Funktion zu nehmen, also einen Report mit $FF ReportID an die Special Mode Pipe schreiben und danach den Antwortreport lesen.
robert.ferralux
Posts: 8
Joined: Wed Dec 06, 2006 4:36 pm
Location: Lkrs. Augsburg

Nach

Post by robert.ferralux »

Hallo der da so heisst wie ich :-),

> ... Special Mode Funktion zu nehmen, also einen Report mit $FF ReportID
> an die Special Mode Pipe schreiben und danach den Antwortreport lesen.

Gibts da irgendwo ein Beispiel in der Doku oder im Forum?
In der Standarddoku finde ich keine Bescheibung des RepID $FF (oder
ich bin Blind)

Das ich den ReportID $FF setzen muß verstehe ich noch, einen Puffer
reservieren (aber wie groß - 4 Bytes?) und dann mit IoKitWrite zum
IOW senden.
Aber mit welcher Funktion lese ich den Antwortreport zurück?


Gruß
ROBERT
Robert Marquardt
Posts: 543
Joined: Mon Dec 01, 2003 6:09 pm

Post by Robert Marquardt »

Dokumentation in IOWarriorDatasheet.pdf Seite 17 Kapitel 5.10.4.
Eine Special Mode Funktion (fast) wie jede andere.

Mit IowKitWrite einen Report schreiben (Format siehe Dokumentation) und direkt danach mit IowKitRead einen Report lesen. IowKitRead wird dann nicht blockieren, da der IOWarrior ja als Antwort einen Report schickt.
robert.ferralux
Posts: 8
Joined: Wed Dec 06, 2006 4:36 pm
Location: Lkrs. Augsburg

Post by robert.ferralux »

Hallo Hr. Marquardt,
danke für die Antwort.
Nach der Umstellung des Codes auf die SpecialModeFunktion mit $FF
bekomme ich nur noch Zufallswerte zurück.
Hier der Codeausschnitt, auch mit verschiedenen Versuchen:
Was ist richtig: IOW_PIPE_IO_PINS oder IOW_PIPE_SPECIAL_MODE!
------------------------------------------------------------------------------------
// Get Current Port-Pin-Statur
LocalReport.ReportID := $FF;
LocalReport.Bytes[0] := $00;
LocalReport.Bytes[1] := $00;
LocalReport.Bytes[2] := $00;
LocalReport.Bytes[3] := $00;
IowKitWrite (IOWarriors[1], IOW_PIPE_IO_PINS, @LocalReport, IOWKIT40_IO_REPORT_SIZE);
// IowKitWrite (IOWarriors[1], IOW_PIPE_SPECIAL_MODE, @LocalReport, IOWKIT40_IO_REPORT_SIZE);

LocalReport.ReportID := $FF;
myBytesRead := IowKitRead (IOWarriors[1], IOW_PIPE_IO_PINS, @LocalReport, IOWKIT40_IO_REPORT_SIZE);
// myBytesRead := IowKitRead (IOWarriors[1], IOW_PIPE_SPECIAL_MODE, @LocalReport, IOWKIT40_IO_REPORT_SIZE);
------------------------------------------------------------------------------------

Auch verstehe ich eins nicht, in meiner Initialiserung will ich alle IOs -
die O's halt - auf 0 setzen. Wenn ich eine der beiden Aufrufe weglasse,
dann hängt mein Programm und kommt erst nach einer Status-Änderung
an den Pins zurück:
------------------------------------------------------------------------------------
{*** USB-Warrior einstellen ***}
procedure TForm1.InitIOPorts;
begin
{*** Richtung auf den Ports vorbereiten ***}
PortVal0 := $FF; // alles Eingang "high"
PortVal1 := $FF; // alles Eingang "high"
PortVal2 := $00; // alles Ausgang "low"
PortVal3 := $00; // alles Ausgang "low"

{*** Richtung auf den Ports setzten (zum IOW senden) ***}
Report.ReportID := 0;
Report.Bytes[0] := PortVal0; // Eingang "high"
Report.Bytes[1] := PortVal1; // Eingang "high"
Report.Bytes[2] := PortVal2; // Ausgang "low"
Report.Bytes[3] := PortVal3; // Ausgang "low"
IowKitWrite (IOWarriors[1], IOW_PIPE_IO_PINS, @Report, IOWKIT40_IO_REPORT_SIZE);

{*** Ports 1x setzten und Rücksetzen !!! sonst geht's nicht ***}
PortVal2 := $FF; // alles Ausgänge "high"
PortVal3 := $FF; // alles Ausgänge "high"
SetOutPorts;
PortVal2 := $00; // alle Ausgänge "low"
PortVal3 := $00; // alle Ausgänge "low"
SetOutPorts;

{*** HIER Ports 1x einlesen !!! sonst geht's nicht ***}
GetInPorts;
end;
------------------------------------------------------------------------------------

Hat noch jemand eine Idee,
oder kann ich mal den kompletten Source posten?

Gruß und danke allen
ROBERT
Robert Marquardt
Posts: 543
Joined: Mon Dec 01, 2003 6:09 pm

Post by Robert Marquardt »

Es ist ein Special Mode, also muss man einen IOWKIT_SPECIAL_REPORT an die IOW_PIPE_SPECIAL_MODE Pipe schreiben und auch von dieser Pipe lesen. Die Laengenangabe ist natuerlich IOWKIT_SPECIAL_REPORT_SIZE.

Code: Select all

var
  LocalReport: IOWKIT_SPECIAL_REPORT;
begin
  FillChar(LocalReport, IOWKIT_SPECIAL_REPORT_SIZE, 0);
  LocalReport.ReportID := $FF;
  IowKitWrite(IOWarriors[1], IOW_PIPE_SPECIAL_MODE, @LocalReport, IOWKIT_SPECIAL_REPORT_SIZE);
  myBytesRead := IowKitRead(IOWarriors[1], IOW_PIPE_SPECIAL_MODE, @LocalReport, IOWKIT_SPECIAL_REPORT_SIZE); 
end;
Die komplette Source besser direkt an mich schicken. marquardt att codemercs dott com.
Post Reply