Quancom Relaiskarten auslesen

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Atuc.

    Quancom Relaiskarten auslesen

    Hallo Forum - Mitglieder,
    ich nutze VB 2010 Express und versuche gerade zwei USBREL64 Karten von Quancom zum laufen zu bringen.
    Also ich habe alles installiert. Abweichend von der Beschreibung bei Quancom habe ich aber nicht die QLib.bas importiert (das führt immer zu Fehlermeldungen beim compile) sondern die Qlib.vb.
    Beide Karen habe ich mit dem Demoprogramm überprüft und funktionieren einwandfrei. Das Demoprogramm erlaubt es die einzelnen Ausgänge ein- bzw auszuschalten und wenn man es aufruft werden die eingeschalteten Relais markiert, die nicht eingeschalteten eben nicht.
    Dann habe ich ein einfaches Programm geschrieben das einzelne Relais ein- bzw ausschaltet und den Status ausgeben soll.

    Dim handle As Integer
    Dim xxx As Integer
    handle = QAPIExtOpenCard(USBREL64, 0)
    If (handle <> 0) Then
    CALL QAPIExtWriteDO1(handle, NumericUpDown1.Value, 1, 0)
    xxx = QAPIExtReadDI1(handle, NumericUpDown1.Value, 0)
    Label1.Text = xxx.ToString
    Call QAPIExtCloseCard(handle)
    End If
    End Sub

    Egal was ich aber mache erhalte ich immer den Wert 0 zurück.

    Bin für alle Ideen dankbar da sich der Support von Quancom nicht meldet.

    Grüße, schönes Wochenende usw ....
    Hallo Manawyrm,
    der Code ist VB 2010 Express.
    Ich habe ein Form mit einem Button, einem Label und einem NumericUpDown Element.
    Als Prototyp sollte und muss das reichen, wenn das funktioniert kann ich ein GUI für meine Anwendung bauen.
    Was brauchst Du noch an Code?
    Grüße ...
    Ich hab letztens auch versucht, eine Relais-Karte anzusteuern. Ich brauchte erstmal ne Zeit, um herauszubekommen, wie das Teil überhaupt angesteuert wird.
    Ich hatte eine Relaiskarte mit 32 Relais'. Das hier dürfte sicher ähnlich sein.


    Also..
    Ich gehe mal davon aus, dass deine Relaiskarte (ähnlich wie meine) in 8 Abschnitte eingeteilt ist. Es gibt also pro Abschnitt 8 Relais (64/8=8)
    Du musst nun um einen bestimmten Relais anzusprechen die angeschaltenen Relais eines Abschnittes rausbekommen. Dafür gibt es ja die Funktion QAPIExtReadDI1
    Wenn du nun als 2. Parameter den Abschnitt des anzusprechenden Relais angibst, kriegst du alle angeschaltenen Relais raus.
    Wenn du nun einen anschalten willst, musst du zu dem Wert, den du grad bekommen hast, die Bytes des anzuschaltenen Relais addieren.
    Wie kriegst du nun die Bytes des anzuschaltenen Relais raus?
    Hier klicken
    -> Dafür brauchst du noch eine Datenklasse, die sieht bei mir so aus:

    VB.NET-Quellcode

    1. Class RelaisInfo
    2. Public digitalByte As Byte
    3. Public digitalPort As Integer
    4. Sub New(ByVal digitalByte As Byte, ByVal digitalPort As Integer)
    5. Me.digitalByte = digitalByte
    6. Me.digitalPort = digitalPort
    7. End Sub
    8. End Class


    Dann brauchst du noch ein Dictionary(Of Integer, RelaisInfo)
    In dem Dictionary speicherst du alle Relaisdaten drinne.
    Bei mir sah das so aus:

    VB.NET-Quellcode

    1. relaisList.Add(0, New RelaisInfo(1, 0))
    2. relaisList.Add(1, New RelaisInfo(2, 0))
    3. relaisList.Add(2, New RelaisInfo(4, 0))
    4. relaisList.Add(3, New RelaisInfo(8, 0))
    5. relaisList.Add(4, New RelaisInfo(16, 0))
    6. relaisList.Add(5, New RelaisInfo(32, 0))
    7. relaisList.Add(6, New RelaisInfo(64, 0))
    8. relaisList.Add(7, New RelaisInfo(128, 0))
    9. relaisList.Add(8, New RelaisInfo(1, 1))
    10. relaisList.Add(9, New RelaisInfo(2, 1))
    11. relaisList.Add(10, New RelaisInfo(4, 1))
    12. relaisList.Add(11, New RelaisInfo(8, 1))
    13. relaisList.Add(12, New RelaisInfo(16, 1))
    14. relaisList.Add(13, New RelaisInfo(32, 1))
    15. relaisList.Add(14, New RelaisInfo(64, 1))
    16. relaisList.Add(15, New RelaisInfo(128, 1))
    17. relaisList.Add(16, New RelaisInfo(1, 2))
    18. relaisList.Add(17, New RelaisInfo(2, 2))
    19. relaisList.Add(18, New RelaisInfo(4, 2))
    20. relaisList.Add(19, New RelaisInfo(8, 2))
    21. relaisList.Add(20, New RelaisInfo(16, 2))
    22. relaisList.Add(21, New RelaisInfo(32, 2))
    23. relaisList.Add(22, New RelaisInfo(64, 2))
    24. relaisList.Add(23, New RelaisInfo(128, 2))
    25. relaisList.Add(24, New RelaisInfo(1, 3))
    26. relaisList.Add(25, New RelaisInfo(2, 3))
    27. relaisList.Add(26, New RelaisInfo(4, 3))
    28. relaisList.Add(27, New RelaisInfo(8, 3))
    29. relaisList.Add(28, New RelaisInfo(16, 3))
    30. relaisList.Add(29, New RelaisInfo(32, 3))
    31. relaisList.Add(30, New RelaisInfo(64, 3))
    32. relaisList.Add(31, New RelaisInfo(128, 3))


    Und wie krieg ich jetzt die Relaisdaten aus dem Dictionary raus?
    Hier klicken
    -> Du musst aus deinem Dictionary die Daten mit dem Key rausholen. Dieser ist hier der Relais. Zurück bekommst du eine Instanz der Klasse RelaisInfo


    Ohja, toll! Und wie kann ich jetzt einen Relais ausmachen?
    Hier klicken
    -> Genauso wie du einen Relais anmachst - nur musst du subtrahieren.
    Es ist bloss wichtig, dass der Relais an sein muss, wenn du ihn ausschalten willst. Gleiches gilt fürs anschalten (es kommt sonst zu unvorsehbaren Komplikationen)



    Da ich ja nett bin, hast du hier mal nen Ansatz
    Hier klicken

    VB.NET-Quellcode

    1. Private Function GetTurnOffByte(Byval relais As Integer) As Byte
    2. Dim tmp As Byte
    3. QAPIExtReadDI1(handle, relaisList(relais).digitalPort, tmp)
    4. tmp -= relaisList(relais).digitalByte
    5. Return tmp
    6. End Function
    7. Private Function GetTurnOnByte(Byval relais As Integer) As Byte
    8. Dim tmp As Byte
    9. QAPIExtReadDI1(handle, relaisList(relais).digitalPort, tmp)
    10. tmp += relaisList(relais).digitalByte
    11. Return tmp
    12. End Function
    13. Sub TurnRelaisOn(Byval relais As Integer)
    14. QAPIExtWriteDO1(handle, relaisList(relais).digitalPort, GetTurnOnByte(relais))
    15. End Sub
    16. Sub TurnRelaisOff(Byval relais As Integer)
    17. QAPIExtWriteD01(handle, relaisList(relais).digitalPort, GetTurnOffByte(relais))
    18. End Sub


    Desweiteren musst du natürlich die RelaisList um 32 Relais nach meinem Prinzip erweitern.
    Funktion kann ich nicht garantieren.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Myrax“ ()

    Hallo Myrax,
    Ich habe zwar 64 Relais aber mir geht es eigentlich nur darum gezielt den Zustand eines Relais auszulesen.
    Das ein / ausschalten geschieht bei meinem Prototypen über die mitgelieferte Software.
    In einem Überwachungsfenster soll einfach nur der Zustand der Relais 1 (also 0), 12 (also 11), 27 (also 26) und 53 angezeigt werden.
    Bei Deiner Lösung finde ich keine Ausleseroutine oder bin ich zu blöd?
    Ich brauche was ganz einfaches so etwas wie IF Relaiszustand (handle, relaisnr) > 0 Then ....

    Kannst Du mir da weiter helfen?

    Vielen Dank!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Atuc“ ()

    NullReferenceException ...

    Myrax schrieb:

    Ich hab letztens auch versucht, eine Relais-Karte anzusteuern. Ich brauchte erstmal ne Zeit, um herauszubekommen, wie das Teil überhaupt angesteuert wird.
    Ich hatte eine Relaiskarte mit 32 Relais'. Das hier dürfte sicher ähnlich sein.


    Also..
    Ich gehe mal davon aus, dass deine Relaiskarte (ähnlich wie meine) in 8 Abschnitte eingeteilt ist. Es gibt also pro Abschnitt 8 Relais (64/8=8)
    Du musst nun um einen bestimmten Relais anzusprechen die angeschaltenen Relais eines Abschnittes rausbekommen. Dafür gibt es ja die Funktion QAPIExtReadDI1
    Wenn du nun als 2. Parameter den Abschnitt des anzusprechenden Relais angibst, kriegst du alle angeschaltenen Relais raus.
    Wenn du nun einen anschalten willst, musst du zu dem Wert, den du grad bekommen hast, die Bytes des anzuschaltenen Relais addieren.
    Wie kriegst du nun die Bytes des anzuschaltenen Relais raus?
    Hier klicken
    -> Dafür brauchst du noch eine Datenklasse, die sieht bei mir so aus:

    VB.NET-Quellcode

    1. Class RelaisInfo
    2. Public digitalByte As Byte
    3. Public digitalPort As Integer
    4. Sub New(ByVal digitalByte As Byte, ByVal digitalPort As Integer)
    5. Me.digitalByte = digitalByte
    6. Me.digitalPort = digitalPort
    7. End Sub
    8. End Class


    Dann brauchst du noch ein Dictionary(Of Integer, RelaisInfo)
    In dem Dictionary speicherst du alle Relaisdaten drinne.
    Bei mir sah das so aus:
    Hier klicken

    Myrax schrieb:

    Wenn ich das aufrufe "relaisList.Add(0, New RelaisInfo(1, 0))" bekomme ich eine Fehlermeldung NullReferenceException.

    Myrax schrieb:

    VB.NET-Quellcode

    1. relaisList.Add(0, New RelaisInfo(1, 0))
    2. relaisList.Add(1, New RelaisInfo(2, 0))
    3. relaisList.Add(2, New RelaisInfo(4, 0))
    4. relaisList.Add(3, New RelaisInfo(8, 0))
    5. relaisList.Add(4, New RelaisInfo(16, 0))
    6. relaisList.Add(5, New RelaisInfo(32, 0))
    7. relaisList.Add(6, New RelaisInfo(64, 0))
    8. relaisList.Add(7, New RelaisInfo(128, 0))
    9. relaisList.Add(8, New RelaisInfo(1, 1))
    10. relaisList.Add(9, New RelaisInfo(2, 1))
    11. relaisList.Add(10, New RelaisInfo(4, 1))
    12. relaisList.Add(11, New RelaisInfo(8, 1))
    13. relaisList.Add(12, New RelaisInfo(16, 1))
    14. relaisList.Add(13, New RelaisInfo(32, 1))
    15. relaisList.Add(14, New RelaisInfo(64, 1))
    16. relaisList.Add(15, New RelaisInfo(128, 1))
    17. relaisList.Add(16, New RelaisInfo(1, 2))
    18. relaisList.Add(17, New RelaisInfo(2, 2))
    19. relaisList.Add(18, New RelaisInfo(4, 2))
    20. relaisList.Add(19, New RelaisInfo(8, 2))
    21. relaisList.Add(20, New RelaisInfo(16, 2))
    22. relaisList.Add(21, New RelaisInfo(32, 2))
    23. relaisList.Add(22, New RelaisInfo(64, 2))
    24. relaisList.Add(23, New RelaisInfo(128, 2))
    25. relaisList.Add(24, New RelaisInfo(1, 3))
    26. relaisList.Add(25, New RelaisInfo(2, 3))
    27. relaisList.Add(26, New RelaisInfo(4, 3))
    28. relaisList.Add(27, New RelaisInfo(8, 3))
    29. relaisList.Add(28, New RelaisInfo(16, 3))
    30. relaisList.Add(29, New RelaisInfo(32, 3))
    31. relaisList.Add(30, New RelaisInfo(64, 3))
    32. relaisList.Add(31, New RelaisInfo(128, 3))

    Myrax schrieb:


    Und wie krieg ich jetzt die Relaisdaten aus dem Dictionary raus?
    Hier klicken
    -> Du musst aus deinem Dictionary die Daten mit dem Key rausholen. Dieser ist hier der Relais. Zurück bekommst du eine Instanz der Klasse RelaisInfo


    Ohja, toll! Und wie kann ich jetzt einen Relais ausmachen?
    Hier klicken
    -> Genauso wie du einen Relais anmachst - nur musst du subtrahieren.
    Es ist bloss wichtig, dass der Relais an sein muss, wenn du ihn ausschalten willst. Gleiches gilt fürs anschalten (es kommt sonst zu unvorsehbaren Komplikationen)



    Da ich ja nett bin, hast du hier mal nen Ansatz
    Hier klicken

    VB.NET-Quellcode

    1. Private Function GetTurnOffByte(Byval relais As Integer) As Byte
    2. Dim tmp As Byte
    3. QAPIExtReadDI1(handle, relaisList(relais).digitalPort, tmp)
    4. tmp -= relaisList(relais).digitalByte
    5. Return tmp
    6. End Function
    7. Private Function GetTurnOnByte(Byval relais As Integer) As Byte
    8. Dim tmp As Byte
    9. QAPIExtReadDI1(handle, relaisList(relais).digitalPort, tmp)
    10. tmp += relaisList(relais).digitalByte
    11. Return tmp
    12. End Function
    13. Sub TurnRelaisOn(Byval relais As Integer)
    14. QAPIExtWriteDO1(handle, relaisList(relais).digitalPort, GetTurnOnByte(relais))
    15. End Sub
    16. Sub TurnRelaisOff(Byval relais As Integer)
    17. QAPIExtWriteD01(handle, relaisList(relais).digitalPort, GetTurnOffByte(relais))
    18. End Sub


    Desweiteren musst du natürlich die RelaisList um 32 Relais nach meinem Prinzip erweitern.
    Funktion kann ich nicht garantieren.
    Sagen wir du hast dein Dictionary relaisList. Vorerst ist relaisList Nothing also nichts. Du musst nun ein neues Dictionary erstellen. Entweder machst du das direkt im Konstruktor, vor dem hinzufügen der Relaisinfos oder du schreibst es nach der Deklaration.
    Du erstellst ein Dictionary(Of Integer, RelaisInfo) mit New Dictionary(Of Integer, RelaisInfo)

    Die Lösung

    So sieht die Lösung aus:
    In der QuanCom Doku ist es dokumentiert im C Code auch implementiert aber nicht in Visual Basic. Auch die Doku selber ist mehr als ...... naja.

    Also hier der Code

    Public Const QAPI_Read_Back_Relais_State = 123

    Public Function Read_Back_Relais_Status(ByVal handle As Integer, ByVal relaisNo As UInteger) As Boolean
    Dim cardNo, relaisState, channelNo, relaisNo_2 As UInteger
    handle = QAPIExtOpenCard(USBREL64, cardNo)
    If handle <> 0 Then
    channelNo = relaisNo \ 32
    relaisNo_2 = relaisNo Mod 32
    relaisState = QAPIExtSpecial(handle, QAPI_Read_Back_Relais_State, channelNo, 0)
    relaisState = relaisState And (2 ^ relaisNo_2)
    If relaisState = 0 Then
    Return False
    Else
    Return True
    End If
    Call QAPIExtCloseCard(handle)
    End If

    End Function