Die drei Fragezeichen

teaage

Level-1
Beiträge
14
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

wenn ich mit TwinCat 3 das Beispielprojekt erstelle, dann steht bei Value immer "<Value of the expression cannot be retrieved.>" und die Werte werden unten auch nicht Live angezeigt.
Komischerweise zählt die Variable, wenn ich sie anklicke.

fragezeichen.JPG
fragezeichen2.JPG

Vielen Dank im Voraus!
teaage
 
Zuletzt bearbeitet:
Das komische ist auch, dass mit folgendem Code nur die festen Werte im Deklarationsteil abgelesen werden und nicht diejenigen, die ich in der SPS mit den Ein- und Ausgänge des EP4374-0002 verknüpfe.

Code:
Imports TwinCAT.Ads
Imports System.IO


Public Class Form1
    Inherits System.Windows.Forms.Form


    Private adsClient As TcAdsClient
    Friend WithEvents TextBox3 As System.Windows.Forms.TextBox
    Friend WithEvents Label3 As System.Windows.Forms.Label
    Friend WithEvents TextBox4 As System.Windows.Forms.TextBox
    Friend WithEvents Label4 As System.Windows.Forms.Label
    Private varHandles(2) As Integer


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim port As Integer
        port = TextBox3.Text
        Try
            adsClient = New TcAdsClient
            adsClient.Connect(port)
            varHandles(0) = adsClient.CreateVariableHandle("MAIN.ausgang1")
            varHandles(1) = adsClient.CreateVariableHandle("MAIN.ausgang2")
            varHandles(2) = adsClient.CreateVariableHandle("MAIN.eingang1")
        Catch err As Exception
            MessageBox.Show(err.Message)
        End Try
    End Sub


    Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        adsClient.Dispose()
    End Sub




    Private Sub btnRead_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRead.Click


        Dim dataStream As AdsStream
        Dim reader As AdsBinaryReader
        Try
            dataStream = New AdsStream(30)
            reader = New AdsBinaryReader(dataStream)


            dataStream.Position = 0
            adsClient.Read(varHandles(0), dataStream)
            textBox1.Text = reader.Read


            dataStream.Position = 0
            adsClient.Read(varHandles(1), dataStream)
            textBox2.Text = reader.Read


            dataStream.Position = 0
            adsClient.Read(varHandles(2), dataStream)
            TextBox4.Text = reader.Read




        Catch err As Exception
            MessageBox.Show(err.Message)
        End Try
    End Sub


    Private Sub btnWrite_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnWrite.Click
        Dim dataStream As AdsStream
        Dim writer As AdsBinaryWriter
        Try
            dataStream = New AdsStream(4)
            writer = New AdsBinaryWriter(dataStream)


            dataStream.Position = 0
            writer.Write(textBox1.Text)
            adsClient.Write(varHandles(0), dataStream)


            dataStream.Position = 0
            writer.Write(textBox2.Text)
            adsClient.Write(varHandles(1), dataStream)


            dataStream.Position = 0
            writer.Write(TextBox4.Text)
            adsClient.Write(varHandles(2), dataStream)
        Catch err As Exception
            MessageBox.Show(err.Message)
        End Try
    End Sub
End Class

Code:
PROGRAM MAIN

VAR
    ausgang1 AT %Q*: INT :=100;
    ausgang2 AT %Q*: INT;
    eingang1 AT %I*: INT;
END_VAR
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
wenn ich mit TwinCat 3 das Beispielprojekt erstelle, dann steht bei Value immer "<Value of the expression cannot be retrieved.>" und die Werte werden unten auch nicht Live angezeigt.

Ich habe gerade im TwinCAT v3.1.4010.0 XAE (VS 2012) die gleiche Deklaration in MAIN eingegeben -> Konfiguration aktiviert -> PLC Projekt geladen und gestartet -> online Werte werden angezeigt.
Unbenannt.GIF
Also generell geht's.
 
Ich danke dir fürs Ausprobieren! Jetzt funktioniert es. Ich habe auch VS2012 installiert und den Code neu gemacht.

Nun bin ich bei einem anderen Problem:

Ich möchte bei einem Modul mit 4 digitalen Ein- und 4 Ausgängen testen, ob diese alle einzeln kommen und die LEDs OK sind.
Doch man sieht natürlich kein Blinken, weil der Code zu schnell ausgeführt wird.
Gibt's in VB.net irgendetwas zum Verzögern? Die Sleep-Funktion funktioniert leider nicht.
Außerdem sind diese if-Schleifen sehr umständlich. Mit for-next habe ich es auch nicht hinbekommen :-(
Hier mein Code:
Code:
Private Sub Button_blinken_Click(sender As Object, e As EventArgs) Handles Button_blinken.Click
        adsClient.WriteAny(digital_out0, True)
        If digital_in0 = True Then
            adsClient.WriteAny(digital_out1, True)
            adsClient.WriteAny(digital_out0, False)
        End If
        If digital_in1 = True Then
            adsClient.WriteAny(digital_out2, True)
            adsClient.WriteAny(digital_out1, False)
        End If
        If digital_in2 = True Then
            adsClient.WriteAny(digital_out3, True)
            adsClient.WriteAny(digital_out2, False)
        End If
        If digital_in3 = True Then
            adsClient.WriteAny(digital_out0, True)
            adsClient.WriteAny(digital_out3, False)
        End If
    End Sub
 
Hallo,
Ich möchte bei einem Modul mit 4 digitalen Ein- und 4 Ausgängen testen, ob diese alle einzeln kommen und die LEDs OK sind.
Doch man sieht natürlich kein Blinken, weil der Code zu schnell ausgeführt wird.
weil der Code zu schnell ausgeführt wird ?
Ich glaube eher, dass es daran liegt, dass du ihn nicht oft enug ausführst.
Was möchtest du denn wann blinken lassen ?

Gibt's in VB.net irgendetwas zum Verzögern? Die Sleep-Funktion funktioniert leider nicht.
Für Hintergrund-Funktionen gäbe es generell mehrere Mögichkeiten.
Die Einfachste (aus meiner Sicht) wäre eine Routine, die du mit einem VB-Timer in dem von dir gewünschten Intervall ausführst.
Du kannst dir natürlich auch einen BackgroundWorker oder einen eigenen Thread dafür erstellen - hier würde dann auch ggf. die Sleep-Methode wieder korrekt arbeiten ...
Das hängt so ein bißchen davon ab, was es werden soll ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich hab von TwinCat jetzt keine Ahnung aber dein Code kommt mir schon etwas komisch vor...

Code:
         If digital_in0 = True Then
            adsClient.WriteAny(digital_out1, True)
            adsClient.WriteAny(digital_out0, False)
        End If                                                        <-- Out1 ist jetzt auf TRUE...

        If digital_in1 = True Then                              <-- Wenn Out 1 TRUE... passiert das nicht im selben Durchlauf? 
            adsClient.WriteAny(digital_out2, True)         <-- Oder wird der neue Zustand von Out1 erst beim nächsten Durchlauf gelesen?
            adsClient.WriteAny(digital_out1, False)
        End If
Wenn du alle LEDs in einem Durchlauf zum leuchten bringen willst braust du tatsächlich irgendeine Verzögerung dazwischen. Sonst wirst du nicht viel sehen.
Oder wie Larry schon sagte die Routiune getimed aufrufen (Dann halt mit ein wenig anderem Code)
 
Zuletzt bearbeitet:
Genau, ich möchte die LEDs nacheinander blinken lassen(also Ausgänge setzen).
Um die Eingänge zu kontrollieren, sollen die nächsten Ausgänge erst gesetzt werden, wenn die jeweiligen Eingänge OK sind.
Dazwischen soll jeweils z.B. eine halbe Sekunde vergehen, damit ich alle LEDs blinken sehen kann.
Normalerweise wird das ganze ja Programm/der ganze Code so extrem schnell ausgeführt, dass man nichts sieht.
Ein Timer führt die komplette If-Routine ja auch nur in einer eingestellten Zeit komplett und viel zu schnell aus.
Ich bräuchte also mehrere Delays im Code oder eine for-next Schleife

So ungefähr müsste es aussehen, aber das mit dem x funktioniert irgendwie nicht so.
Code:
        For x As Integer = 0 To 3
            If digital_in(x) = True Then
                adsClient.WriteAny(digital_out(x + 1), True)
                adsClient.WriteAny(digital_out(x), False)
            End If
            Threading.Thread.Sleep(500)
        Next x
 
Nein ... du brauchst im Visual Studio eine Prozedur, die zyklisch aufgerufen wird (z.B.), in der du die Eingänge einliesst und dann entsprechend darauf reagierst.
Das könntest du z.B. mit einem Timer (im Visual Studio lösen).

Hier mal ein Beispiel :
Code:
[COLOR=blue]Imports[/COLOR] System.ComponentModel
[COLOR=blue]Public[/COLOR] [COLOR=blue]Class[/COLOR] [COLOR=#2b91af]Taktgeber[/COLOR]
    [COLOR=blue]Inherits[/COLOR] [COLOR=#2b91af]Timer[/COLOR]
 
[COLOR=blue]#Region[/COLOR] [COLOR=#a31515]"Konstruktor / Dispose"[/COLOR]
 
    [COLOR=blue]Sub[/COLOR] [COLOR=blue]New[/COLOR]()
        Frequenz = 2
        [COLOR=blue]MyBase[/COLOR].Interval = 500 / Frequenz
 
        [COLOR=blue]AddHandler[/COLOR] [COLOR=blue]MyBase[/COLOR].Tick, [COLOR=blue]AddressOf[/COLOR] BlinkTimer_Zyklus
        [COLOR=blue]MyBase[/COLOR].Start()
    [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR]
 
    [COLOR=blue]Sub[/COLOR] [COLOR=blue]New[/COLOR]([COLOR=blue]ByVal[/COLOR] frequenz [COLOR=blue]As[/COLOR] [COLOR=blue]Single[/COLOR])
        [COLOR=blue]If[/COLOR] (frequenz < 0.5) [COLOR=blue]Or[/COLOR] (frequenz > 10) [COLOR=blue]Then[/COLOR] frequenz = 2
        [COLOR=blue]MyBase[/COLOR].Interval = 500 / frequenz
 
        [COLOR=blue]AddHandler[/COLOR] [COLOR=blue]MyBase[/COLOR].Tick, [COLOR=blue]AddressOf[/COLOR] BlinkTimer_Zyklus
        [COLOR=blue]MyBase[/COLOR].Start()
    [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR]
 
    [COLOR=blue]Protected[/COLOR] [COLOR=blue]Overrides[/COLOR] [COLOR=blue]Sub[/COLOR] Dispose([COLOR=blue]ByVal[/COLOR] disposing [COLOR=blue]As[/COLOR] [COLOR=blue]Boolean[/COLOR])
        [COLOR=blue]MyBase[/COLOR].Stop()
        [COLOR=blue]RemoveHandler[/COLOR] [COLOR=blue]MyBase[/COLOR].Tick, [COLOR=blue]AddressOf[/COLOR] BlinkTimer_Zyklus
        [COLOR=blue]MyBase[/COLOR].Dispose(disposing)
    [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR]
 
[COLOR=blue]#End[/COLOR] [COLOR=blue]Region[/COLOR]
 
[COLOR=blue]#Region[/COLOR] [COLOR=#a31515]"Blink-Funktionalität"[/COLOR]
 
    [COLOR=blue]Public[/COLOR] Takt [COLOR=blue]As[/COLOR] [COLOR=blue]Boolean[/COLOR] = [COLOR=blue]False[/COLOR]
 
    [COLOR=green]''' [/COLOR][COLOR=gray]<summary>[/COLOR]
    [COLOR=green]''' ragiert auf den Blink-Timer-Takt und erzeugt ein entsprechendes Event[/COLOR]
    [COLOR=green]''' [/COLOR][COLOR=gray]</summary>[/COLOR]
    [COLOR=green]''' [/COLOR][COLOR=gray]<param name=[/COLOR][COLOR=gray]"sender"[/COLOR][COLOR=gray]></param>[/COLOR]
    [COLOR=green]''' [/COLOR][COLOR=gray]<param name=[/COLOR][COLOR=gray]"e"[/COLOR][COLOR=gray]></param>[/COLOR]
    [COLOR=green]''' [/COLOR][COLOR=gray]<remarks></remarks>[/COLOR]
    [COLOR=blue]Private[/COLOR] [COLOR=blue]Sub[/COLOR] BlinkTimer_Zyklus([COLOR=blue]ByVal[/COLOR] sender [COLOR=blue]As[/COLOR] [COLOR=blue]Object[/COLOR], [COLOR=blue]ByVal[/COLOR] e [COLOR=blue]As[/COLOR] [COLOR=#2b91af]EventArgs[/COLOR])
        Takt = [COLOR=blue]Not[/COLOR] Takt
        [COLOR=blue]RaiseEvent[/COLOR] Changed([COLOR=blue]Me[/COLOR], Takt)
    [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR]
 
    [COLOR=blue]Public[/COLOR] [COLOR=blue]Event[/COLOR] Changed([COLOR=blue]ByVal[/COLOR] sender [COLOR=blue]As[/COLOR] [COLOR=blue]Object[/COLOR], [COLOR=blue]ByVal[/COLOR] status [COLOR=blue]As[/COLOR] [COLOR=blue]Boolean[/COLOR])
 
[COLOR=blue]#End[/COLOR] [COLOR=blue]Region[/COLOR]
 
[COLOR=blue]#Region[/COLOR] [COLOR=#a31515]"Properties zur Darstellung"[/COLOR]
 
    <[COLOR=#2b91af]Category[/COLOR]([COLOR=#a31515]"Verhalten"[/COLOR]), [COLOR=#2b91af]Description[/COLOR]([COLOR=#a31515]"Blink-Frequenz in Hz"[/COLOR])>
    <[COLOR=#2b91af]RefreshProperties[/COLOR]([COLOR=#2b91af]RefreshProperties[/COLOR].All)>
    [COLOR=blue]Property[/COLOR] Frequenz [COLOR=blue]As[/COLOR] [COLOR=blue]Single[/COLOR]
        [COLOR=blue]Get[/COLOR]
            [COLOR=blue]Return[/COLOR] 500 / [COLOR=blue]MyBase[/COLOR].Interval
        [COLOR=blue]End[/COLOR] [COLOR=blue]Get[/COLOR]
        [COLOR=blue]Set[/COLOR]([COLOR=blue]ByVal[/COLOR] value [COLOR=blue]As[/COLOR] [COLOR=blue]Single[/COLOR])
            [COLOR=blue]MyBase[/COLOR].Interval = 500 / value
        [COLOR=blue]End[/COLOR] [COLOR=blue]Set[/COLOR]
    [COLOR=blue]End[/COLOR] [COLOR=blue]Property[/COLOR]
 
    <[COLOR=#2b91af]Category[/COLOR]([COLOR=#a31515]"Verhalten"[/COLOR]), [COLOR=#2b91af]Description[/COLOR]([COLOR=#a31515]"Blink-Takt-Interval in Millisekunden"[/COLOR])>
    <[COLOR=#2b91af]RefreshProperties[/COLOR]([COLOR=#2b91af]RefreshProperties[/COLOR].All)>
    [COLOR=blue]Shadows[/COLOR] [COLOR=blue]Property[/COLOR] Interval [COLOR=blue]As[/COLOR] [COLOR=blue]Integer[/COLOR]
        [COLOR=blue]Get[/COLOR]
            [COLOR=blue]Return[/COLOR] [COLOR=blue]MyBase[/COLOR].Interval * 2
        [COLOR=blue]End[/COLOR] [COLOR=blue]Get[/COLOR]
        [COLOR=blue]Set[/COLOR]([COLOR=blue]ByVal[/COLOR] value [COLOR=blue]As[/COLOR] [COLOR=blue]Integer[/COLOR])
            [COLOR=blue]MyBase[/COLOR].Interval = value / 2
        [COLOR=blue]End[/COLOR] [COLOR=blue]Set[/COLOR]
    [COLOR=blue]End[/COLOR] [COLOR=blue]Property[/COLOR]
 
[COLOR=blue]#End[/COLOR] [COLOR=blue]Region[/COLOR]
 
[COLOR=blue]End[/COLOR] [COLOR=blue]Class[/COLOR]

Diese Klasse kannst du nun in deinen Code intergrieren (mit "WithEvents MeinTaktgeber as new Taktgeber(10)" ) und dann das Event davon nutzen um deine Einlese-Ausgabe-Routine zu betreiben ...

Gruß
Larry
 
wenn ich mit TwinCat 3 das Beispielprojekt erstelle, dann steht bei Value immer "<Value of the expression cannot be retrieved.>" und die Werte werden unten auch nicht Live angezeigt.
Komischerweise zählt die Variable, wenn ich sie anklicke.
Schließe alle offenen Tabs. Danach kannst du die POU wieder öffnen und es sollte etwas angezeigt werden.
Das soll auftreten, wenn man zu viele Variablen online betrachtet (hat). Dein Projekt ist aber so klein, dass das nicht der Grund sein kann. Ich habe das aber auch manchmal erst nach Öffnen von vielen POUs, manchmal direkt nach Öffnen von zwei kleinen POUs.
 
Nun bin ich bei einem anderen Problem:

Ich möchte bei einem Modul mit 4 digitalen Ein- und 4 Ausgängen testen, ob diese alle einzeln kommen und die LEDs OK sind.

Nehmt es mir nicht übel, aber dafür brauche ich nicht eine Zeile Code! Einfach auf die Ausgangsklemme gehen, dort auf den Kanal -> Online -> Werte schreiben. Zeitansatz dafür sind ein paar Sekunden und die LED bleibt so lange an wie ich das möchte ..
 
Zurück
Oben