Das Problem besteht vom Bus Richtung Arduino.
Eine hohe Auslastung des Arduino ist ja (vermutlich?) mit hoher Buslast immer gegeben. Es werden, soweit ich das verstehe, ja alle Telegramme empfangen (versucht zu empfangen) und dann quasi gefiltert welches für den Arduino/das Gerät von Relevanz ist und ausgewertet.
Ankündigung
Einklappen
Keine Ankündigung bisher.
ARDUINO am KNX
Einklappen
X
-
KNX -> Arduino
oder
Arduino -> KNX
?
Hohe Last auf dem µController?
Einen Kommentar schreiben:
-
Nach einiger Zeit im produktiven Einsatz habe ich ein "verlorenes" Telegramm an meinem Arduino+TP-Uart zu verzeichnen. Läßt sich das irgendwie "Onboard" verbessern, oder muss man damit aufgrund der Einschränkungen durch Library/Arduino leben?
Einen Kommentar schreiben:
-
Das habe ich mir schon gedacht. Irgendwo muss ja unterschieden werden zwischen relevanten und nicht relevanten Telegrammen.
Die Funktion sieht jetzt erstmal so aus
Falls sich jemand für den kompletten Code interessiert, habe ich den derzeitigen Stand mal angehängt.Code:{ const long interval = 200; // time between blinks in ms. static bool switchState = true; static byte sequencePosition = 0; static unsigned long previousMillis = 0; unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; if (sequencePosition < numberOfBlinks * 2) { // blink switchState = !switchState; sequencePosition++; digitalWrite(LED, switchState); } else { blinkEnd = true; sequencePosition = 0; } } }
Der Großteil ist von Peterich hier aus dem Forum übernommen. Für Verbesserungen bin ich immer offen (bin nur Code Copy-Paster).
Es geht darum einen Wiegand-Reader an den Bus anzubinden. Ich habe das nur um ein paar Kleinigkeiten für meinen Reader (34bit) und Status sowie Abschaltung für die Leseeinheit ergänzt.
Falls Interesse besteht, kann ich nach Fertigstellung dazu ein eigenes Thema zur Dokumentation machen.
Ziel war es möglichst günstig (50€ all incl.) einen optisch vertretbaren, wetterfesten Reader zu haben, der ohne Zusatzversorgung auskommt und direkt über den Bus kommuniziert.Angehängte Dateien
- Likes 1
Einen Kommentar schreiben:
-
Das mit der Lib ist normal. Das "Event unknown" wird ja nur bei serieller Konsole geschrieben, kostet im Normalbetrieb also keine Zeit. Eine if-Abfrage kostet auch nur ein paar µs. Insgesamt ist die Performance am KNX aber begrenzt, das musste ich auch schon feststellen, gerade wenn man nur 8MHz hat :-(
In der Lib gibts auch einige delay(), die erstmal alles für kurze Zeit zum Stillstand bringen.
Einen Kommentar schreiben:
-
Jetzt warst Du schneller...schön, dass es bis hierher schonmal funzt :-)
Einen Kommentar schreiben:
-
Jetzt sehe ichs, da wars ganz unten...da passt es, aber nicht mehr in den folgenden Codeauszügen.
Zeig doch mal den letzten Stand, ist auch für den Leser verwirrend was jetzt umgesetzt ist oder nicht.
Einen Kommentar schreiben:
-
Also, wie es aussieht funktionieren die "static" deklarierten Sachen im ursprünglichen Code, aber das
muss mit oben rein.Code:[B]previousMillis = currentMillis;[/B]
Danke nochmal an dreamy1
Zumindest tut es so einigermaßen, solange man es nicht mit den Intervallen übertreibt.
Also alles < 200ms schafft der Arduino wohl nicht so recht zeitnah neben den ganzen KNX-Aufgaben.*
Noch eine Verständnisfrage:
Ist es technisch bedingt normal, dass der Arduino quasi bei jedem Telegram auf dem Bus einmal bei
"vorbei rennt" und "Event UNKNOWN" ruft?Code:void eventKNX() { KnxTpUartSerialEventType eType = knx.serialEvent(); if (eType == TPUART_RESET_INDICATION) { } else if (eType == UNKNOWN) { Serial.println("Event UNKNOWN"); }
Was im Umkehrschluss heißt, je mehr auf dem Bus los ist, desto weniger Zeit bleibt für andere Aufgaben.
*an der Stelle nochmal der Hinweis, ich habe bei mir derzeit die Ultra-Low-Budget/Cost Version Mini Pro mit 3,3V@8MHz im Einsatz, kein Wunder also.
Einen Kommentar schreiben:
-
War das nicht im ursprünglichen Code so? Ich bin bald ganz verwirrt...Zitat von dreamy1 Beitrag anzeigenWas mir noch auffällt: die previousMillis müssen direkt in der ersten if-Schleife gesetzt werden (ansonsten kommen immer unterschiedliche Codelaufzeiten hinzu, je nachdem ob die zweite if-Schleife oder die else-Schleife durchlaufen wird):
Einen Kommentar schreiben:
-
Was mir noch auffällt: die previousMillis müssen direkt in der ersten if-Schleife gesetzt werden (ansonsten kommen immer unterschiedliche Codelaufzeiten hinzu, je nachdem ob die zweite if-Schleife oder die else-Schleife durchlaufen wird):
Code:void accessgranted(){ ..... unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { [B] previousMillis = currentMillis;[/B] if (sequencePosition < numberOfBlinks * 2) { // blink digitalWrite(LED, switchState); switchState = !switchState; sequencePosition++; } else { blinkEnd = true; sequencePosition = 0; } } }Zuletzt geändert von dreamy1; 23.08.2019, 22:21.
Einen Kommentar schreiben:
-
Das habe ich bereits versucht, bringt aber auch keine Änderung. Irgendwas beißt sich wohl gegenseitig.
Wenn die Funtkion mit Schreiben auf die entsprechende GA aufgerufen wird ergeben sich zwei kurze Blinksignale, manchmal auch nur eines, manchmal so eineinhalb ungleich lang. Immer nur etwa 100ms lang oder auch kürzer. Aber nie einheitlich. Unabhängig davon welchen Wert man für "interval" angibt.
Einen Kommentar schreiben:
-
Deklariere mal "static byte sequencePosition = 0;" global oben im Sketch als "byte sequencePosition = 0;", also außerhalb der void(). So wie ich das sehe, wird diese Variable immer mit dem Aufruf der void() erstmal auf Null gesetzt, also wird da auch nix hochgezählt. Das dürfte auch für die anderen statischen Variablen gelten.
Einen Kommentar schreiben:
-

So tut es aber auch nicht wirklich besser...? Oder was habe ich wieder übersehen?
Code:void accessgranted(){ const long interval = 150; // time between blinks in ms. static bool switchState = true; static byte sequencePosition = 0; static unsigned long previousMillis = 0; unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { if (sequencePosition < numberOfBlinks * 2) { // blink digitalWrite(LED, switchState); switchState = !switchState; sequencePosition++; } else { blinkEnd = true; sequencePosition = 0; previousMillis = currentMillis; } } }
Einen Kommentar schreiben:
-
Nein, dein Fehler ist, dass du previousMillis gar keine Zeit lässt, um auf dein Intervall zu kommen, weil du es bei jedem Funktionsaufruf mit currentMillis gleichsetzt.
Code:void accessgranted(){ const long interval = 150; // time between blinks in ms. static bool switchState = true; static byte sequencePosition = 0; static unsigned long previousMillis = 0; unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { if (sequencePosition < numberOfBlinks * 2) { // blink digitalWrite(LED, switchState); switchState = !switchState; sequencePosition++; previousMillis = currentMillis; } else { blinkEnd = true; sequencePosition = 0; } } }
Einen Kommentar schreiben:
-
Gibt es irgendwelche "Spezialitäten" in Kombination mit der KNX Library zu beachten?
Ich versuche hier neben KNX Abfragen und Sendebefehlen (läuft soweit gut) so etwas wie ein paar simple Blink-Codes (BlinkWithoutDelay) zu realisieren, aber es will so gar nicht klappen. Als eigenständiger Code funktioniert dieser hingegen wunderbar.
Im loop habe ich dabei so etwas wieCode:const byte numberOfBlinks = 2;
Und dannCode:if (!blinkEnd) { accessgranted(); }
Die LED schaltet in diesem Fall nur einmal ein bzw. um.Code:void accessgranted(){ const long interval = 150; // time between blinks in ms. static bool switchState = true; static byte sequencePosition = 0; static unsigned long previousMillis = 0; unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { if (sequencePosition < numberOfBlinks * 2) { // blink switchState = !switchState; sequencePosition++; digitalWrite(LED, switchState); } else { blinkEnd = true; sequencePosition = 0; } } previousMillis = currentMillis; }
Einen Kommentar schreiben:


Einen Kommentar schreiben: