Hallo! Ich habe eine grundsätzliche Frage zum Thema UART und Interrupt. Wie kann ich den Empfangsinterrupt beim Atmega austricksen? Ich bin relativ neu bei C/C++ und Mikrocontroller. Habe mich aber glaub einigermaßen in die Materie reingewurstelt und baue aktuell einen LED-Tisch mit folgender Hardware: -100 ws2812b RGB-LED in einer 10x10 Matrix -Atmega1284P@16MHz mit Quarz -verschiedener Kleinkram für Touch-Erkennung, Kommunikation, Stromversorgung etc Mein Programm funktioniert soweit. Sicherlich nicht schön und effizient programmiert, aber ich kann durch ein Menü verschiedene Animationen aufrufen, Einstellungen im EEPROM vornehmen, Signalquelle umschalten und später kommen noch eine handvoll einfache Spiele hinzu. Nun will ich gerne eine RS232-Schnittstelle implementieren um Steuerbefehle empfangen zu können. Hardware mit Max232 ist bereits vorhanden. Grundsätzlich denke ich, der Code ist machbar, zumal es ja offenbar viele gute Libs hat. Ich stehe aber an der Stelle vor einer Verständnissfrage: Die LEDs werden über BitBanging angesteuert mit der Lib light_ws2812 https://github.com/cpldcpu/light_ws2812/blob/master/README.md Die Sequenz für 100 LED dauert etwa 3ms. Aufruf erfolgt aktuell noch in einem Timer-Interrupt, der mit ~51Hz ausgeführt wird. Da die LED empfindlich auf Timing reagieren darf die Sequenz nicht unterbrochen werden. Also ist ein Aufruf in der main mit abgeschaltenen Interrupts auch nicht Besser. Bei Standard-9600Baud können ja aber in den ~3ms Zeit fast 30 Zeichen reintrudeln und den RX-Speicher hoffnungslos überlaufen lassen. Ein Interrupt um empfangene Zeichen in einen größeren Puffer wegzuschreiben geht nicht, da er ja die LED-Sequenz unterbrechen würde. Habt ihr Ideen, wie ich das Problem umgehen könnte? Einen Attiny814 als Puffer dazwischen? (DSub->RX Attiny, TX Attiny->RX Mega1284, TX Mega1284->DSub) Scheint mir aber übertrieben, aufwendig, kompliziert und Fehleranfällig. Gibt es eine Art TTL-Baustein, der die Daten "Zwischenspeichern" und wenn Zeit ist (also auf Befehl vom 1284P) weiterleiten kann? Oder habt ihr Vorschläge, wie ich das ganze einfach in Software lösen kann? Oder sehe ich das alles einfach nur zu kritisch und das geht alles problemlos? Viele Grüße, Sum
Möchtest du die Datenrate des UART noch einmal nachrechnen? Baud ist nicht Byte/s sondern Bit/s. Du könntest als primitivsten Ansatz die Baudrate herunter setzen auf zB ungefährliche 2400Bd.
Falls die HW sich noch ändern lässt: Teile deine 10x10 Pixel auf in 4 Quadranten mit 5x5 pixel, und steuere die eins nach dem anderen. Jedes Quadrant braucht dann weniger als 1ms zum ansteuern, und dir bleibt noch ein bisschen Zeit um zu schauen ob beim UART was angekommen ist. Nachdem alle 4 Quadrandten angesteuert sind nimmst du dir Zeit um die UART-Zeichen auszuwerten, Kaffee zu trinken usw, bis die 20ms (bei deine ~50Hz) vergangen sind. Etwa so:
1 | LOOP EVERY 20ms |
2 | FOR q = 0 .. 3 |
3 | do output to quadrant(q) |
4 | read character from UART, if present |
5 | END FOR |
6 | process all characters from UART |
7 | do other stuff |
8 | END LOOP |
:
Bearbeitet durch User
Sum schrieb: > Habt ihr Ideen, wie ich das Problem umgehen könnte? In Assembler programmieren und die Ausgabe an die LEDs nicht per dümmlichem Bitbanging abwickeln. > Oder habt ihr Vorschläge, wie ich das ganze einfach in Software lösen > kann? Einfach ist relativ. Kommt ganz auf die Fähigkeiten des Betrachters an. Einen Teil brauchst du jedenfalls nicht mehr selber entwickeln. Die unterbrechbare WS28xx-Ausgabe für bis zu 1024 WS28xx in Assembler habe ich schon fertig und bereits vor einiger Zeit hier gepostet. Ist zwar für einen Tiny4313@20MHz designed, läßt sich aber ganz sicher auch auf einen Mega1284P@16MHz anpassen, wenn deine Kohle nicht reicht, um einen 20MHz-Quarz für 23 Cent zu kaufen. Wenn du dir ihn hingegen leisten kannst, brauchst du sogar bloss zwei Zeilen (die ersten beiden) zu ändern und der Code läuft sofort nach Neuassemblierung auch auf einem Mega1284P. Allzu viel Luft für weitere Interupts neben dem für die LED-Ausgabe benutzten ist zwar nicht, aber einer geht auf jeden Fall noch. Ich habe z.B. in einem Projekt eine DDS-Soundausgabe mit 78kHz Interruptfolgefrequenz parallel zu der LED-Ausgabe drin. UART mit selbst 115,2 kBit/s sollte also keinerlei Probleme bereiten, da ist die maximale Interruptfolgefrequenz ja nur lächerliche 11,5kHz. Allerdings muss die ISR hochoptimiert sein, ähnlich wie es auch die der LED-Ausgabe ist. Viel weniger kritisch ist Code, der auschließlich in main() läuft. Du hast bei 20Mhz ungefähr 45% der Rechenzeit dort zur Verfügung und der Code dort kommt auch ziemlich regelmäßig zum Laufen, die längste Pause habe ich jetzt nicht im Kopf, sie ist aber in jedem Fall deutlich kürzer als die Dauer der Übertragung des "Datenpaketes" für eine LED. Also deutlich kürzer als 24/800000=30µs.
@Sum (Gast) >Ich habe eine grundsätzliche Frage zum Thema UART und Interrupt. Wie >kann ich den Empfangsinterrupt beim Atmega austricksen? Warum sollte man das? >Ich bin relativ neu bei C/C++ und Mikrocontroller. Eben DARUM sollte man eher weniger tricksen. >Nun will ich gerne eine RS232-Schnittstelle implementieren um >Steuerbefehle empfangen zu können. Da muss man rein gar nichts tricksen. >Die LEDs werden über BitBanging angesteuert mit der Lib light_ws2812 >https://github.com/cpldcpu/light_ws2812/blob/maste... Hmm. >Die Sequenz für 100 LED dauert etwa 3ms. Aufruf erfolgt aktuell noch in >einem Timer-Interrupt, der mit ~51Hz ausgeführt wird. Da liegt schon das erste Problem. Diese Aktion gehört in die Hauptschleife! Siehe Interrupt. > Da die LED >empfindlich auf Timing reagieren darf die Sequenz nicht unterbrochen >werden. Für EINE LED! Aber man muss nicht die drei ms durchweg senden. > Also ist ein Aufruf in der main mit abgeschaltenen Interrupts >auch nicht Besser. Doch. Denn man kann, sinnvolle Programmierung vorausgesetzt, an weniger zeitkritischen Stellen den UART abfragen (neudeutsch polling) und die Daten zwischenspeichern, z.B. in einem FIFO. >Bei Standard-9600Baud können ja aber in den ~3ms Zeit fast 30 Zeichen >reintrudeln DREI! Siehe Baud. >und den RX-Speicher hoffnungslos überlaufen lassen. Ein >Interrupt um empfangene Zeichen in einen größeren Puffer wegzuschreiben >geht nicht, da er ja die LED-Sequenz unterbrechen würde. Ja. >Habt ihr Ideen, wie ich das Problem umgehen könnte? Einen Attiny814 als >Puffer dazwischen? NÖ. >(DSub->RX Attiny, TX Attiny->RX Mega1284, TX Mega1284->DSub) Scheint mir >aber übertrieben, aufwendig, kompliziert und Fehleranfällig. Eben. >Gibt es eine Art TTL-Baustein, der die Daten "Zwischenspeichern" und >wenn Zeit ist (also auf Befehl vom 1284P) weiterleiten kann? Hirn 2.0 mit gescheiter Programmierung. GGf. nutzt man das SPI, um die Daten in die LEDs zu takten, das entspannt die Sache auch nochmal deutlich. >Oder sehe ich das alles einfach nur zu kritisch und das geht alles >problemlos? Es geht, wenn gleich man schon ein paar KONZEPTE kennen und umsetzen muss. Mit tricksen hat das wenig zu tun.
Da der Resetcode erst nach 50us erkannt wird, hat man zwischen jedem BIT für die LEDs 50us Zeit, andere Dinge zu tun. Praktisch reicht es wahrscheinlich, nach jedem Byte oder gar jeder LED oder einer Anzahl N LEDs eine kleine Pause zu machen und den UART abzufragen. Langweilig, zumal 50us bei 16 MHz eine kleine Ewigkeit sind ;-)
Sum schrieb: > Die Sequenz für 100 LED dauert etwa 3ms. Ja. > Bei Standard-9600Baud können ja aber in den ~3ms Zeit fast 30 Zeichen > reintrudeln und den RX-Speicher hoffnungslos überlaufen lassen.> Nein, es sind (fast) 3 Zeichen. > Aufruf erfolgt aktuell noch in > einem Timer-Interrupt, der mit ~51Hz ausgeführt wird. In der ISR irgendetwas ausführen, vor allem etwas, das 3ms dauert, ist eine schlechte Idee. > Habt ihr Ideen, wie ich das Problem umgehen könnte? Einen Attiny814 als > Puffer dazwischen? Nein. 51Hz = 19ms - 3ms = 16ms für andere Sachen. Also, Steuerbefehl (1 Byt) wird gesendet - nur ein Byte und dann wird auf Antwort gewartet. Dieses Byte landet in UART Data Register, RXC Flag wird gesetzt. Nachdem Daten für WS2812 raus sind, wird TXC geprüft. Falls gesetzt, hat dein uC noch 16ms Zeit um eine Bestätigung raus zuschicken, kompleten Steuerbefehl zu empfangen und auszuführen. Wo ist da ein Problem ?
:
Bearbeitet durch User
Falk B. schrieb: Etwas vorweg: Musst du immer 50 Zeilen zitieren, um dann ein "Hmmm" oder "Ja" von sich zu geben ? >> Da die LED >>empfindlich auf Timing reagieren darf die Sequenz nicht unterbrochen >>werden. > > Für EINE LED! Aber man muss nicht die drei ms durchweg senden. LOL. Natürlich muss man das. Falk B. schrieb: > Da der Resetcode erst nach 50us erkannt wird, hat man zwischen jedem BIT > für die LEDs 50us Zeit, andere Dinge zu tun. Praktisch reicht es > wahrscheinlich, nach jedem Byte oder gar jeder LED oder einer Anzahl N Selbstverständlich sind das keine 50us, besonders WS2812B sind da sehr zickig, alles über 20us ist schon reines Gluck. Und warum soll er dauernd hin und her springen, wenn zwischen Auffrischen 16ms Zeit ist (etwa 800 Mal so lange). Falk B. schrieb: > Hirn 2.0 mit gescheiter Programmierung. Ja, anstatt 1000 Worte schreiben ohne etwas gescheites zu sagen oder eine konkrete Lösung anzubieten. > GGf. nutzt man das SPI, um die > Daten in die LEDs zu takten, das entspannt die Sache auch nochmal > deutlich. Selbstverständlich nicht. WS2812 mit SPI ohne DMA ansteuern ist und bleibt Blödsinn. Entweder man bleibt in der SPI Schleife, dann ist da kein Unterschied zu Bitbanging, oder man arbeitet mit Interrupt, dann kann der uC von laufendem Hin- und Herspringen zwischen main() und ISR sowieso nichts gescheites machen.
:
Bearbeitet durch User
@ Marc Vesely (Firma: Vescomp) (logarithmus) > Musst du immer 50 Zeilen zitieren, um dann ein "Hmmm" oder "Ja" von > sich zu geben ? Hmmm, vielleicht ;-) >>> Da die LED >>>empfindlich auf Timing reagieren darf die Sequenz nicht unterbrochen >>>werden. > >> Für EINE LED! Aber man muss nicht die drei ms durchweg senden. > LOL. > Natürlich muss man das. Nö. Siehe Datenblatt. Reset wird erst nach 50us Sendepause auf LOW erkannt. Schrieb ich bereits.
Falk B. schrieb: > Nö. Siehe Datenblatt. Reset wird erst nach 50us Sendepause auf LOW > erkannt. Schrieb ich bereits. Ja, das steht da. Aber die meisten WS2812b haben das Datenblatt leider nicht gelesen.
@ Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase) >> Nö. Siehe Datenblatt. Reset wird erst nach 50us Sendepause auf LOW >> erkannt. Schrieb ich bereits. >Ja, das steht da. Aber die meisten WS2812b haben das Datenblatt leider >nicht gelesen. Selbst wenn es nur 20us sind, ist das mehr als ausreichend.
Falk B. schrieb: > Da der Resetcode erst nach 50us erkannt wird [...] > Praktisch reicht es > wahrscheinlich, nach jedem Byte oder gar jeder LED oder einer Anzahl N > LEDs eine kleine Pause zu machen und den UART abzufragen. Das hast du niemals wirklich selber probiert, soviel ist mal sicher. Ein typisches Dummschwätzer-Posting. Tatsächlich ist es nämlich so: Man darf sich keinesfalls darauf verlassen, dass erst ab 50µs ein Reset erkannt wird, das passiert viel früher. Nämlich bei der ersten LED der Kette. Dort zuerst und in der Folge auch bei den weiteren LEDs... Die 50µS des DB beschreiben nämlich die Anforderungen an den Reset für eine Kette maximaler Länge. Erst ab dieser Resetdauer ist garantiert, dass auch die letzte LED einer Kette maximaler Länge den Reset noch als solchen erkennt. Trotzdem ist dein Ansatz nicht völlig daneben. Man kann tatsächlich anderen Code in einer dümmlichen Bitbanging-Ausgabe unterbringen, der das Timing verzerrt, ohne die LED-Ausgabe insgesamt aus dem Tritt zu bringen. Das liegt daran, dass die "Sensitivität" der WS28xx generell auf die Dauer der *Low*-Pegel im Signal geeicht ist, nicht nur bezüglich des Reset, sondern auch bezüglich der Daten. Das ermöglicht es, die High-Phasen eines jeden Datenbit DB-widrig zu verlängern. Allerdings nur in Maßen, irgendwann kommen die LEDs aus dem Tritt. Je länger die Kette und je länger die High-Phase, desto wahrscheinlicher. Bei voller Kettenlänge ist dieser Trick praktisch nicht mehr anwendbar, da sollte man tunlichst auch in dieser Beziehung an das vom DB vorgegebene Timing halten. > Langweilig, > zumal 50us bei 16 MHz eine kleine Ewigkeit sind ;-) Es geht nicht um die 50µs, die frei sind, sondern um die 3ms (bei 100 LEDs), die es nicht sind. Das wenigstens solltest du doch begriffen haben...
Leider muss ich Falk recht geben. Ein falsches Hardwarekonzept macht die Sache schwieriger. Es würde schon gehen wenn man die Rs232 mit Flusskontrolle benutzt. So werden immer dann Zeichen gelesen wenn die Daten auf den Streifen geschrieben wurden. Die Flusskontrolle ist aber so ziemlich aus der Mode gekommen.
@ c-hater (Gast) >Das hast du niemals wirklich selber probiert, soviel ist mal sicher. Ein >typisches Dummschwätzer-Posting. Das sagt der Richtige ;-) Nimm deine Pillen und verschone uns mit deinen Beiträgen. Danke.
Der Streifen macht bei allem über 9µS einen Reset bzw. übernimmt die Values in die PWM Register.
Falk B. schrieb: > Selbst wenn es nur 20us sind, ist das mehr als ausreichend. Wofür ? Aber selbst wenn es 50us sind, warum und wozu ? Es besteht ganz einfach keine Notwendigkeit, UART in dieser Zeit abzufragen. Taster usw. vielleicht, da magst du Recht haben, aber UART muss bestimmt nicht abgefragt werden. Kann natürlich, bringt aber überhaupt keine Vorteile.
@Sum (Gast) >-100 ws2812b RGB-LED in einer 10x10 Matrix >Die LEDs werden über BitBanging angesteuert mit der Lib light_ws2812 >Die Sequenz für 100 LED dauert etwa 3ms. Nun ja, es ist wohl eher KEINE LED-Matrix, so wie es der Rest der Welt versteht, sondern eine Kette aus 100 intelligenten LEDs. Die 100 LEDs könnte man in 4x25 Stränge aufteilen, dann dauert es nur noch ~750us pro Kette. Dazwischen kann man in Ruhe andere Dinge tun, ganz ohne Stress. Und da du es so oder so Bitbanging machst, geht das auch mit mehreren, verschiedenen Pins. Ob das diese Lib kann weiß ich nicht.
@ Marc Vesely (Firma: Vescomp) (logarithmus) >> Selbst wenn es nur 20us sind, ist das mehr als ausreichend. > Wofür ? Um den UART abzufragen, schrieb ich schon mehrfach. > Es besteht ganz einfach keine Notwendigkeit, UART in dieser Zeit > abzufragen. Doch, vor allem wenn man, warum auch immer, höhere Baudraten OHNE Flußkontrolle nutzen will. Kann man machen, muss man nicht. > Taster usw. vielleicht, da magst du Recht haben, aber UART muss > bestimmt nicht abgefragt werden. > Kann natürlich, bringt aber überhaupt keine Vorteile. Doch, siehe oben.
Falk B. schrieb: > Nimm deine Pillen und verschone uns mit deinen Beiträgen. Danke. Nein, das werde ich ganz sicher nicht tun. Im Gegenteil, dieses Posting von dir liefert mir die Steilvorlage, dich komplett zu demontieren. Denn ich kann durch Code jede meiner Aussagen in diesem Thread für jeden nachvollziehbar beweisen. Was dir hingegen äußerst schwerfallen dürfte... Willst du wirklich für jeden offensichtlich als Vollarsch mit Gottkomplex dastehen oder bist du bereit jetzt einen Rückzieher zu machen? Last chance...
Falk B. schrieb: >> Kann natürlich, bringt aber überhaupt keine Vorteile. > > Doch, siehe oben. Nein, siehe unten. PC (oder wer auch immer) sendet ein einziges Byte und wartet auf Antwort (wobei es gar kein warten ist, sondern nur Abfrage von Zeit zu Zeit ob ein Zeichen empfangen worden ist). Kann sowieso nicht länger als 3ms dauern. Danach hat der PC (oder wer auch immer) 16ms Zeit um den Rest zu senden und der uC hat genauso viel Zeit, um das auszuführen. >> Es besteht ganz einfach keine Notwendigkeit, UART in dieser Zeit >> abzufragen. > > Doch, vor allem wenn man, warum auch immer, höhere Baudraten OHNE > Flußkontrolle nutzen will. Was haben höhere Baudraten damit zu tun ? Und warum sollte die andere Seite Kilobits ohne Flußkontrolle losschicken ? Und mit Flusskontrolle bist du genausoweit wie mit 1 Byte und anschliessender Bestätigung, weil der PC (oder wer auch immer) immer auf RTS oder CTS warten muss. Wo siehst du da irgendwelche Vorteile ? Hältst du beim Autofahren auch alle paar Km an, um Sprit aus dem Kanister nachzufüllen, anstatt eine Tankstelle anzufahren wenn es Zeit dazu ist ?
Da die UART ja bis zu 3 Byte puffern kann, sollte das doch mit den 3ms und 9600 Baud noch gerade so hinhauen. Vorzugsweise schreibt man den RX-Interrupt als do{}while() Schleife und spart so den Prolog/Epilog-Overhead ein, falls wirklich 3 Byte angekommen sind. Und mit Parity und 2 Stopbits hat man etwas mehr Luft (2,4Byte/3ms). P.S.: Ist doch nicht so einfach, es können ja schon 9 Bits gekommen sein, wenn der Timerinterrupt zuschlägt. Man müßte also noch mit Pin-Change den RXD-Pin überwachen und gegebenenfalls den Timerinterrupt verzögern, bis das Byte komplett ist. D.h. Pin-Change Interrupt sperrt den Timerinterrupt und der RX-Interrupt gibt ihn wieder frei. 4800Baud wäre die einfachere Lösung.
:
Bearbeitet durch User
Peter D. schrieb: > Da die UART ja bis zu 3 Byte puffern kann Nein, das kann sie nicht. Es sind nur (knapp) 2 Byte. Nämlich ein volles Byte in (received) UDR und alle Datenbits eines zweiten Bytes im Empfangsschieberegister, abzüglich des Stop-Bits dieses Bytes, Denn dessen Eintreffen verwirft bereits den Inhalt von UDR und ersetzt ihn durch den Inhalt des Scheiberegisters. Und selbst wenn es wirklich drei wären: Was machst du mit diesem Ansatz, wenn es sich nicht um 100, sondern um 200 WS28xx-LEDs handelt. Die UART-Bitrate halbieren? Und wenn es 1024 sind, noch zweimal halbieren?... Das wäre zumindest dann ziemlich kontraproduktiv, wenn über eben diesen Kanal die Daten für die LEDs reinkommen sollen, findest du nicht auch? Meine Fresse, warum gebt ihr nicht einfach zu, dass C hier einfach mal Scheisse ist. Selbst noch mit dem Trick, den ich euch verraten habe, der es euch ermöglichen würde, die unsägliche C-Schwäche bei ISRs zumindest für kurze Ketten hinreichend gut auch in dümmlichen Bitbanging-Ausgaben zu umschiffen. Jedenfalls wenn man ihn (im Gegensatz zu diesem unsäglich inkompetenten Brunner-Typen wenigstens begreift und sinnvoll anwendet...)
Peter D. schrieb: > D.h. Pin-Change Interrupt sperrt den Timerinterrupt und der RX-Interrupt > gibt ihn wieder frei. > 4800Baud wäre die einfachere Lösung. Nein. Die einfachere (und einzig sinnvolle) Lösung habe ich schon genannt. Dieses rumhantieren mit Rx- und Pinchange Interrupts verkompliziert die Sache nur unnötig. Ohne DMA gehen immer 3ms verloren, es sei denn, man macht es mit Assembler und Tricks (wie c-hater). Und selbst dann muss es durchdacht und miteinander verschachtelt sein, damit auch was sinnvolles daraus wird. Das alles ist aber ganz einfach unnötig - es ist genügend Zeit vorhanden, vor allem da man (nach Bestätigung) das Ganze mit 250KB oder mit 500KB anstatt mit 4800B rausjagen kann...
:
Bearbeitet durch User
c-hater schrieb: > Peter D. schrieb: > >> Da die UART ja bis zu 3 Byte puffern kann > > Nein, das kann sie nicht. Es sind nur (knapp) 2 Byte. Nämlich ein volles > Byte in (received) UDR und alle Datenbits eines zweiten Bytes im > Empfangsschieberegister, abzüglich des Stop-Bits dieses Bytes, Denn > dessen Eintreffen verwirft bereits den Inhalt von UDR und ersetzt ihn > durch den Inhalt des Scheiberegisters. Vielleicht solltest du doch mal einen Blick ins Datenblatt riskieren, c-hater. So steht's im Abschnitt zur USART: ... The Data OverRun (DORn) Flag indicates data loss due to a receiver buffer full condition. A Data OverRun occurs when the receive buffer is full (two characters), it is a new character waiting in the Receive Shift Register, and a new start bit is detected. ... Macht drei, wenn ich mich nicht verrechnet habe, und der Overrun tritt erst beim darauffolgenden Startbit auf.
c-hater schrieb: > Nein, das kann sie nicht. Es sind nur (knapp) 2 Byte. OMG. Probiers doch wenigstens mal aus, eh Du solchen Schmarrn erzählst. Schreib eine Schleife aus 5s Delay und Senden solange RX-Puffer nicht leer. Und dann gibt z.B. "12345" ein. Die '1' und '2' landen im Doppelpuffer. Die '3' bleibt solange im Schieberegister, bis das nächste Startbit erkannt wird. Wenn Du alles innerhalb der 5s gesendet hast, kriegst Du somit nach 5s "125" zurück.
Rainer B. schrieb: > Macht drei, wenn ich mich nicht verrechnet habe, und der Overrun tritt > erst beim darauffolgenden Startbit auf. Nein, du hast dich nicht verrechnet aber das ist auch egal. Wenn DOR Flag gesetzt wird, ist es unmöglich festzustellen, wieviele Bytes schon ev. verlorengegangen sind - es kann ja schon 2 Bytes vorher gesetzt worden sein. Und wenn so etwas passiert, dann ist irgendetwas mit deinem Program falsch. Anstatt eine 100% sichere und ungefähr 100 Mal schnellere Prozedur mit Bestätigung zu implementieren, wird auf einer überaus langsamen und unsicheren Prozedur bestanden. Macht Ihr das beruflich auch so ?
Danke für eure Hinweise. Ich hab mich an ein paar Stellen blöd ausgedrückt, sorry dafür. Also, erstens: natürlich keine 30 Zeichen, da habe ich in der Eile Symbolrate mit Zeichen vertan, aber Symbole hier gleich Bit. Sehe ich das richtig, dass ein 8N1 Datenbyte bei 9600baud incl Start/Stop dann 1042 Mikrosekunden benötigt? Zweitens: die Senderoutine kommt auch wieder aus dem Int raus, ist mir durchaus bewusst. Den Timertick habe ich ja schon. Hatte nur Probleme im Code und zur Fehlersuche hatte ich umgebaut. @Falk Brunner Ja, elektrisch gesehen eine Kette aus 100 LEDs. Mechanisch als 10x10 Matrix aufgebaut, nicht in snakelines. Dass der Aber feud in main nicht besser ist meinte ich in Bezug auf den Sende-Code, der nicht unterbrochen werden darf. @Eric B. Deine Idee gefällt mir eigentlich. Leider geht es nicht, die externe Quelle ist ein "LEDPlayer" auf den ich per Relais umschalten kann, dieser hat nur einen Ausgang. Für die komplexen Bilder wird der per USB vom PC angesteuert. @c-hater Wie kann man deinen Code unterbrechen? Kann man deinen asm-Code in C einbinden? Ich habe von Assembler keine Ahnung, werde also in C weitermachen. Aber soweit ich weiß ist die von mir verwendete Lib auch in (mindestens teilweise) in Assembler geschrieben. @Marc Vesely Ich muss mal schauen, ob ich noch einen Pin freiräumen kann für Flusskontrolle. Unterstützt denn jeder USB-RS232 Adapter die Flusskontrolle von Haus aus? Wenn ich mit dem com-Port verbinde, wollte ich nichts justieren müssen, daher auch die 9,6kbaud. Wenn das jeder com-Port standardmäßig unterstützt wäre das ja auch eine saubere Lösung.
Sum schrieb: > Flusskontrolle Ehe du lötest oder programmierst, sieh dir mal die Spezifikation an. Es ist mitnichten so, dass der Sender verstummt, sobald CTS wegfällt. Je nach UART Bauform kann da noch einiges tröpfeln. Flowcontrol per RTS-CTS oder per Software ist nicht trivial.
Sum schrieb: > @Marc Vesely > Unterstützt denn jeder USB-RS232 Adapter die > Flusskontrolle von Haus aus? Nein. > Wenn ich mit dem com-Port verbinde, wollte > ich nichts justieren müssen, daher auch die 9,6kbaud. Brauchst du auch nicht, du hast ja einen Quarz. Sum schrieb: > Wenn das jeder com-Port standardmäßig unterstützt wäre das ja auch eine > saubere Lösung. Wozu ? Marc V. schrieb: > Nein. > 51Hz = 19ms - 3ms = 16ms für andere Sachen. > > Also, Steuerbefehl (1 Byt) wird gesendet - nur ein Byte und dann wird > auf Antwort gewartet. > Dieses Byte landet in UART Data Register, RXC Flag wird gesetzt. > Nachdem Daten für WS2812 raus sind, wird RXC geprüft. > Falls gesetzt, hat dein uC noch 16ms Zeit um eine Bestätigung raus > zuschicken, kompleten Steuerbefehl zu empfangen und auszuführen. Du kannst es natürlich machen, wie es dir beliebt, anstatt so: Marc V. schrieb: > Das alles ist aber ganz einfach unnötig - es ist genügend Zeit > vorhanden, vor allem da man (nach Bestätigung) das Ganze mit 250KB > oder mit 500KB anstatt mit 4800B rausjagen kann... P.S. Deine MEGA hat mit 16MHz Quarz von 250Kbps bis 1Mbps einen Fehler von genau keinen, nämlich 0,0%.
:
Bearbeitet durch User
Georg G. schrieb: > Baud ist > nicht Byte/s sondern Bit/s. Nö.... sondern Schrittgeschwindigkeit. Also Schritte pro Sekunde. Es gibt Verfahren die mehrere Bits pro Schritt übertragen können. Zum Beispiel 8 Bits bei Bei 256-QAM.
BlaBla schrieb: > Nö.... Bei dem hier in 99.9% aller Fälle verwendeten Verfahren besteht kein Unterschied. Und wenn wir schon bei kleinen Rosinen sind: Nicht Schritte sondern Symbole wäre korrekt.
Georg G. schrieb: > Nicht Schritte > sondern Symbole wäre korrekt. Nö.... beides richtig. Nur moderner ;-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.