Timer Probleme ...

  • VB.NET

Es gibt 36 Antworten in diesem Thema. Der letzte Beitrag () ist von M.P..

    ok wie schon geschrieben habe ich das mal von ProcessControl - Struktur - Umgesetzt, klappt auch alles besten ...

    jetzt habe ich ja die Daten im Array vorliegen,
    wie kann ich das High und Low byte zusammen setzen und mir dieses Dec Zahl in einer Textbox ausgeben lassen

    denn ..

    textbox.text = cstr(byteIn(5) & byte(6))
    geht ja wol nicht da er sie mir ja nur zusammen setzt ..

    wenn du lust hast kannst du es dir mal ansehen ???
    Dateien
    • Strukture.zip

      (188,2 kB, 136 mal heruntergeladen, zuletzt: )
    Meinst Du so was:

    VB.NET-Quellcode

    1. Dim by() As Byte = {123, 234}
    2. Dim dd As Integer = 256 * by(0) + by(1)
    3. textbox.text = dd.ToString
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Auweia..jetzt hab ich was losgetreten..:-))

    An PICO FLOP:

    Events nicht, weil die mir nur sagen, das da Zeichen angekommen sind. Aber die Events sagen mir nicht, ob das schon alles ist, oder da noch was "nachkommt".

    Die Methode mit dem Timer mag zwar etwas "stupide" aussehen, funktioniert aber vom Prinzip her sehr zuverlässig, bis jetzt unter allen Basic Dialekten (und Versionen) und mit allen ModBus Geräten, die mir unter die Finger gekommen sind. Das einzige, was mir jemals negativ aufgefallen ist: Man verschenkt durch das damit "starre" Timing vielleicht etwas Übertragungszeit. Das wird aber nur dann wirklich negativ, wenn man den "Time-Slot" von 1s (Üblich im Modbusbereich) unbedingt einhalten muß, und man trotzdem während dieser Zeit mehr als 200 Datenwörter bei 9600baud (auch sehr beliebt bei Modbus) durch die Leitung quetschen muß. Auch kritisch dann: Das Abfragen von Daten von MEHREREN Slaves, oder "gestückelte" Abfragen von Daten, halt verteilt auf mehrere Anfragen. Man muß in diesen Fällen dann immer wieder neu das nette Frage-Antwort Spiel anstossen, mit dem ganzen Overhaed und den Wartezeiten.

    Jetzt zum Reduzieren des Durchlaufwertes von 10 auf 5:

    Natürlich wird es "gefühlt" dann schneller, weil du damit den "Timeslot" von 1s (10x100ms) reduzierst auf 0.5s (5x100ms). Dein Programm fragt und bekommt dann eben alle 0.5s seine Daten.

    Das kannst du natürlich gerne so machen. Du kannst noch weiter runter....probiers aus! Aber Achtung: Der "Modbus-Slave" braucht auch noch ein wenig Rechenleistung seiner CPU für sich selbst, um die Daten selber zu ermitteln, zu bearbeiten (ev. scalieren). Es gibt Modbusgeräte, die dann irgendwann ins "Straucheln" kommen. Kurioserweise treten dann nicht nur Fehler auf, sondern die Geräte kommen dann manchmal sogar überhaupt nicht mehr aus dem Straucheln heraus! :-)) Dann hilft manchmal nur noch ein Hard-Reset...

    Die Spitze ist: Setze die "Verarbeitung" deiner Daten in Schritt 1, gleich hinter das Senden der Anforderung. Dann kannst du, während die Kommunikation auf der Schnittstelle noch läuft, die Daten vom letzten Mal verarbeiten. Du brauchst also eigentlich effektiv nur noch 2 Schritte.

    Auch die Zykluszeit des Timers kannst du vielleicht noch weiter herabsetzen für mehr Speed.

    Prüfe aber unbedingt immer auch die Checksumme der empfangenen Daten. Wenn die nicht stimmt, ist das der ultimative Hinweis, das du es "übertrieben" hast. :)

    Du kommst bei solchen "kritischen" Timings dann aber zwangsweise auch in den Bereich, wo Windows selbst dir einen Strich durch die Rechnung machen kann. Das damals unter Win NT 4.0 sehr zuverlässige preemtive Multitasking ist über Win2000 und WinXP anscheinend nicht besser, sondern deutlich schlechter geworden. Das betrifft leider auch die "Bedienung" der seriellen Ports.

    Genauso war das Thema mit den "bescheidenen" seriellen Portbausteinen am Anfang dieses Threads KEIN Scherz! Sowas kann schnell zum KO führen, wenn die Hardware nicht gut ist...

    Gruß

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

    hallo,
    ich habe das mal umgesetzt mit diesen Timern, und es passt für meine zwecke muss ich sagen zhu 100 %,
    sicher kann man das ganze noch verfeiner und anpassen, aber da ich anfänger bin, und bis jetzt alles so läuft wie
    ich es mir vorgestellt habe, bin ich zu frieden...

    denn es kann nur eine verarbeitet werden und das ist gut so, timer stehen bei mir alle auf 100, bei 80 ist schluss ...

    kannst du mir bitte erklähren was du mit befehls listen gemeint hast ..
    jetzt läuft es wie beim alten Basik ab von oben nach unten ..

    aber so wie ich sehe hast du da schon einioge erfahrungen mit diesen bus, wir benutzen ihn für die steuerung
    von jalousien, bessergest wir haben, jetzt läuft alles über EIB ... auch wieder so ein ding wo ich einarbeiten soll ..

    aber eine frage habe ich noch, wie soll ich in dieser Schleife eine überprüfung einbauen, also was soll ich überprüfen ..

    die länge der daten, einen bestimmten wert an einer bestimmte stelle also da stehe noch etwas auf dem schlauch ..???

    wenn ich mal mit allen fertig bin kannst du es dir ja mal ansen..

    ProcessControl schrieb:

    Events nicht, weil die mir nur sagen, das da Zeichen angekommen sind. Aber die Events sagen mir nicht, ob das schon alles ist, oder da noch was "nachkommt".

    Das brauchen sie auch nicht ...
    (Ich hab von Modbus 0 Ahnung, aber dein Byte Nummer 3 ist üblicherweise die Lösung ...)

    Pseudocode:
    Buffer = Empty
    ...
    Event GotData
    ResetTimeout
    If state = watingforanser then
    Buffer.AppendData
    If buffer.Length > 2 then
    packetsize = buffer(2)
    if buffer.size=packetsize then PacketComplete

    Den einzigen Timer braucht man dann für den TimeOut
    Event Timer
    Timout += 1
    If Timeout >= foo then state = timout

    Falls man mit Datenübetragungen arbeitet, die keine Paketgröße im Header haben nimmt man statt Timout dann halt "Ready" (also nach x ms keine Änderung im Empfangspuffer mehr).

    Been there, done that ...

    BTW: Die Größe des (internen) Hardwarepuffers des UART (16550?) spielt bei dem ganzen afaik eh keine große Rolle, da zu Zeiten als der 16 Byte groß war (heute immer noch?) auch schon Übertragungsraten mit 115 kBit funzten, obwohl dann rund 14.000 byte/sekunde durchflutschten, dh pro ms schon 14 byte und das ist IMMER noch zu schnell um es mit nem Timer zu handlen (Auflösung MAX 17 ms). Der UART löst aber ja nen Interrupt aus und dann schreibt Windows den Empfangspuffer in einen eigenen, der deutlich größer ist
    ok ich stehe im wald, byte nummer drei ist immer 0x00, wie soll ich da eine ünberprüfung vornehemen, das ganze telegramm hat eine länge von 49 byte,
    je nachdem was ich abfrage ???

    sende : 01 03 01 00 00 00 17 xx xx
    antwort : 01 03 2e 00 00 94 ...... xx xx

    wenn an allen ausgängen das selbe programiert worden ist, sehen alle telegramme gleich aus ...

    wie kann soll ich so was prüfen ...

    zur zeit prüfe ich mit den angeforderten(49) bytes und den Threshold(49), wobei ich ja da nur die länge überprüfe ... ????

    Leider nicht ganz so simpel...

    picoflop schrieb:

    statt Timout dann halt "Ready" (also nach x ms keine Änderung im Empfangspuffer mehr).




    DAS hört sich interessant an. Kannte ich unter VB6 noch nicht, muß mal genauer bei VB2010 nachlesen. Macht dann aber auch nix anderes, als mit der Schrittkette. Wartet einfach, bis sich nix mehr tut. (Nur "schöner" halt! :-))

    Bei Modbus sind die Antworten leider NICHT immer das, was man erwartet. (Also in seinem Fall auch nicht GARANTIERT immer 49 bytes. Modbus Slaves senden (meistens) auch eine Fehlernachricht, wenn sie ein Problem detektiert haben.

    Die simpelste Methode ist dann:

    Merken, das mehr als 2 bytes im Empfangspuffer sind UND keine Neuen mehr dazukommen. Dann: Prüfen, ob erwartete Länge und Checksumme stimmen. Wenn ja, dann weiterverarbeiten. Wenn nein, dann eben nichts tun und beim nächsten Durchgang dann wieder sein Glück aufs Neue versuchen.

    Mit viel Mühe kann man dann noch prüfen "WAS" die Fehlermeldung bedeutet. Da gibts dann genormte Codes für Checksummenfehler, Schreiben auf geschützte Bereiche, usw, usw...Aber: Hier kommt dann auch leider wieder die "Herstellerwürze" ins Spiel. Man müßte also am besten eine komplette Liste aller Modbusfunktionen und auch der Reaktionen der Geräte haben, um das wirklich gut zu machen.

    Zur Hardware:

    Muß ich leider widersprechen: Die Hardware ist absolut nicht trivial! Es mag sein, das schon mit billigen Chips Modems recht gut funktionieren. Das scheint aber leider beim VB6 ComControl (VB2010 habe ich noch nicht allzuviel Erfahrung) schon recht schnell "ins Auge" zu gehen.

    Erfahrung: Solange die zu empfangenen bytes komplett in den Hardware-Eingangspuffer des Chips passen, geht eigentlich immer alles klar. Wenn aber noch mehr Bytes kommen, MUSS Windows (Oder das ComControl) die Daten schnell genug übernehmen in seinen eigenen Puffer, damit der Hardware Puffer nicht überläuft. Und genau DA haperts unter VB(6) manchmal gewaltig. Da geht dann auch schonmal das eine oder andere Byte verloren. Manchmal scheint auch Windows selbst zumindest "mit" dran Schuld zu sein, meistens bei hoher CPU Last. Dem kann man dann eigentlich nur noch mit Mehrkernmaschinen und hohem CPU Takt entgegen wirken. Aber wie gesagt: Ich habe (noch) keine große Erfahrung unter VB2010, mag sein, das es da besser geht.

    Bei den USB zu seriell Wandlern ist es ähnlich, es gibt gute und schlechte...manchmal wird aber auch ein gutes Gerät hier durch einen miesen Treiber "degradiert". (Habe z.B. so ein Gerät in der Firma, was unbedingt auch unter WinXP den älteren Win2000 Treiber braucht. Der XP Treiber taugt nicht...) Meistens macht sich das dann dadurch bemerkbar, das die Syncronisierung bei längeren Nachrichten "am Stück" verloren geht. (Ab ca. 200 Byte tauchen dann auf einmal Paritätsfehler auf).

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

    Ruhig bleiben...:-) Der "Wald" ist garnicht so dunkel...:-)

    M.P. schrieb:

    ok ich stehe im wald, byte nummer drei ist immer 0x00, wie soll ich da eine ünberprüfung vornehemen, das ganze telegramm hat eine länge von 49 byte,
    je nachdem was ich abfrage ???

    sende : 01 03 01 00 00 00 17 xx xx
    antwort : 01 03 2e 00 00 94 ...... xx xx

    wenn an allen ausgängen das selbe programiert worden ist, sehen alle telegramme gleich aus ...

    wie kann soll ich so was prüfen ...

    zur zeit prüfe ich mit den angeforderten(49) bytes und den Threshold(49), wobei ich ja da nur die länge überprüfe ... ????


    Also:

    Du solltest die ersten 3 Bytes , die Gesamtlänge, und auch die Checksumme prüfen.

    In den ersten 3 Bytes stehen die Modbus-"Slave"-Nummer deines Gerätes (1), die "Wiederholung" deines Anforderungscodes (3), und die Anzahl der Datenbytes (2E). Diese 3 Dinge müssen stimmen, sonst taugen die Daten nicht!

    Man sollte halt falsche Daten lieber verwerfen, als unbedingt damit weiterarbeiten, nur damit die Speed stimmt.

    Zur "Befehlsliste", bzw. Komplexität:

    Modbus kommt aus der Industrie, und ist auch für größere Installationen geeignet! Stell dir einfach eine Produktionsumgebung in einer chemischen Fabrik mit Tausenden von Signalen vor, welche über mehrere Modbus-Segmente mit jeweils bis zu 253 (Slaveadressen 0 und 255 gehen nicht, sind reserviert!) Modbus Slaves eingelesen und eben auch geschrieben werden.

    In so einer Umgebung braucht man dann (auch um den Überblick nicht zu verlieren) tatsächlich (teils dynamisch erzeugte) "Befehlslisten". In den denen stehen solche Sachen wie:

    1. Lese Register 12 bis 14 von Slave Nr.8 in Puffer Nr. 10 bis 12 (Zur Verarbeitung)

    2. Lese Register 20 von Slave 2 und schreibe Datenwort direkt wieder raus nach Slave 24 Register 26 (Direktübertragung)

    3. usw,usw...

    Auch möglich:

    Wenn du einen Modbus-Slave vor dir hast, der IO Signale auf den Registern 10 bis 20 zur Verfügung stellt, aber die (Hardware) IO für Register 14 ist nicht vorhanden, bzw. hat einen Fehler, kann es sein, das der Slave das Lesen von diesem Register "verweigert" (Sowas gibts wirklich!). Dann müßtest du also einzeln erst 10 bis 13 lesen, und dann nochmal 15-20.

    In den obigen Fällen sind "Befehlslisten" dann sehr hilfreich, um das Handling von der "tiefergehenden Byte-Zauberei" etwas zu abstrahieren und einfach simpler zu gestalten.
    also ich hab das jetzt so gemacht ...

    ich bilde jetzt eine CRC summe aus den ersten 3 byte + der länge,
    da sie mir ja bekannt ist, diese prüfe ich dann mit den ankommenden telegramm,
    indem ich mir auch von diesen ersten 3 byte und der länge des array die crc summe berechnen lasse,
    dies vergleiche ich dann in einer abfrage, sollte es nicht stimmen wird der erste schritt wiederholt ....
    also besser als vorher, wenn ich es mit den timern zeiten nicht übertreibe bekomme ich keine fehler mehr ..
    jetzt werd ich es mal versuchen gewisse dinge auszulagern in ner classe oder so ...

    Und dann will mal sehen wie das mit den ereigniss listen geht ...

    Thread schließen?

    Was spricht dagegen, diesen Thread nun erstmal zu schließen? Und später neu zu eröffnen, wenn es ans "Eingemachte" gehen sollte...natürlich!

    Speziell dein Gedanke mit der Klasse ist auch bei mir nicht neu, da ich auch immer gerne etwas haben wollte, was ich einfach wiederverwenden kann. Hab das mal mit mehreren Leuten (damals unter VB6) versucht. Der Grundgedanke damals war ein ActivX oder eine Klasse, die nur noch mit Befehlslisten arbeitet und alles andere selbstständig macht. Die Gruppe hat sich aber dann sehr schnell "aufgelöst", da jeder andere Prioritäten hatte oder andere Vorstellungen. Am Ende hat doch wieder jeder seine eigene Suppe gekocht. Das einzige übriggebliebene wirkliche "Universelle" aus meiner Arbeit von damals ist ein kleines VB6 Programm, das Modbus Master oder Slave per serieller Schnittstelle spricht, via DDE z.B. auch mit Excel klarkommt und ausserdem Netzwerkkomunikation zu anderen Stationen via FileIO beherrscht. Also gewissermaßen eine "Eierlegende Wollmilchsau". Das Ding ist als Einziges dann bis vor 2 Jahren immer noch weiterentwickelt worden und auch heute noch vielfach im Einsatz. (In teilweise recht "kuriosen" oder "phantasievollen" Konfigurationen)

    Wenn sich hier ein paar Leutz finden sollten, würde ich auch wohl gerne unter VB2010 einen "Neuanfang" wagen! Modbus-Hardware gibts noch immer zuhaufe und es kommen auch immer noch neue Geräte hinzu. Die Dinger taugen auch zum Privatgebrauch bei Installationen und sind mittlerweile recht preiswert geworden. (z.B. von Fa. Wago oder auch Fa. Spectra). Aber auch in der Industrie gehts in Sachen Modbus immer noch "rund". Der "Burner" dort ist z.B. das Remote-IO System "IS1" von Fa. Stahl. Auch spricht bis heute noch jedes Leitsystem oder jede SPS Modbus.

    Wenn also hier jemand ernsthaft Interesse hat, bei sowas mitzumischen, gerne mal bei mir melden. Aber bitte dann wirklich ernstgemeint! Und mit wenigstens "etwas" Bezug zur Realität (will sagen, mit echter Hardware auf dem heimischen Tisch oder auf der Werkbank im Job!) Ich wäre dann auch durchaus bereit, einige Dinge (Software), für die ich sonst Geld nehme, hier kostenlos beizusteuern. (Als Motivation)