Hallo zusammen hallo Herr Landolt,
habe ueber einen "schoen-zu-haben" nachgedacht was bei vielen
Kommunikationsschnittstellen zum Einsatz kommt - blitzende LED bei
Datenuebertragung.
Nun habe ich mich gefragt was die eleganteste/Rechenleistung beste
Variante waere eine LED blitzen zu lassen waehrend Daten beim USART
empfangen werden ueber mittels Interrupt (und dieses Prinzip dann
uebertragen beim Senden).
Meine Variante sieht so aus (Beispielcode), das geht bestimmt noch
besser eventuell mit einem Timer aber optimierter hinsichtlich Leistung?
> das geht bestimmt noch besser
Ich hätte ad hoc gesagt, das geht so gar nicht: sbi/cbi auf PIN? Wenn es
nicht ein ganz alter AVR8 ist, dann wird mit 'sbi PIN..' der Ausgang
getoggelt, während 'cbi PIN..' nichts bewirkt. Also wird es da schon
irgendwie blinken, aber wohl nicht so wie gewünscht.
Ich habe es nicht ausprobiert, vermute aber zwei Probleme:
- selbst bei 9600 Bd ist das Blinken für das Auge nicht wahrnehmbar
- in einer Empfangspause leuchtet die LED permanent mit einer
Wahrscheinlichkeit von 50 %
(ad hoc: 'aus dem Augenblick heraus', spontan)
Mir fällt spontan nichts Gescheites ein, wenn nicht von anderer Seite
eine Idee kommt, setze ich mich vielleicht morgen mal dran.
Nur soviel: das ist im jetzigen Zustand vielleicht gar nicht so
schlecht, bei konstantem Empfangsstrom dämmert die LED vor sich hin und
kurze Empfangspausen erzeugen ein Blinken; nur sollte die LED bei langen
Pausen ausgehen, nach meinem Empfinden.
S. Landolt schrieb:> Mir fällt spontan nichts Gescheites ein, wenn nicht von anderer> Seite> eine Idee kommt, setze ich mich vielleicht morgen mal dran.> Nur soviel: das ist im jetzigen Zustand vielleicht gar nicht so> schlecht, bei konstantem Empfangsstrom dämmert die LED vor sich hin und> kurze Empfangspausen erzeugen ein Blinken; nur sollte die LED bei langen> Pausen ausgehen, nach meinem Empfinden.
Zugegeben sbi/cbi sind nicht optimal dafuer ist die Funktion schonmal
gegeben auch wenn nicht wie gewuenscht jedoch aber Zeitoptimiert.
Ich koennte mir vorstellen ein Register abzufragen/Zaehler erhoehen und
einen Timer mit dazubringen der den Zustand von Port C Pin 0 (nur
Beispiel) auf 0 setzt (LED aus)
Kann man sich nicht eines der 3 USART Register zunutzen machen und bits
auszulesen um die LED blitzen zu lassen?
USART wird nichts bringen: bei einem konstanten Strom mit zum Beispiel
115200 Bd und 8N1 hat man einen Takt von 11.52 kHz, das Blinken wird zum
Dauer-Dämmer-Licht.
Wenn man einen Timer dafür opfert, sollte es ein Kinderspiel sein.
Alles weitere morgen
wünsche einen Guten Abend
Was ist denn die Aufgabe? Zum Blitzen kann man doch einfach eine
High-Effizient direkt an RX/TX hängen. Z.B. eine High-Effizient in rot
mit 10k an 3/5V direkt am Controller oder mit 20k gegen Masse vor bzw.
hinter dem Inverter. Und wenn es ganz sicher sein soll, dann halt noch
antiparallel eine Diode.
Und wenn es in Code passieren sollte, dann reicht es normalerweise aus,
die am Anfang der Routine anzuschalten und am Ende wieder aus. Dann
natürlich mit 10mA etwa. Sollte es 1µs dauern und Du hast jede ms ein
Zeichen, dann sind das 10µA effektiv, also so gerade ausreichend.
Solltest Du einen wesentlich schnelleren Prozessor haben, dann wirst Du
auch einen RTOS-Tick von 1ms oder was vergleichbares haben. Dann einfach
an im Interrupt (egal ob schon an oder nicht) und Aus im Ticker (egal ob
schon aus oder nicht).
Beim Senden ist es einfacher, da kann man quasi einfach dann abschalten,
wenn kein Zeichen mehr gesendet werden soll.
A. S. schrieb:> Und wenn es in Code passieren sollte, dann reicht es normalerweise aus,> die am Anfang der Routine anzuschalten und am Ende wieder aus. Dann> natürlich mit 10mA etwa. Sollte es 1µs dauern und Du hast jede ms ein> Zeichen, dann sind das 10µA effektiv, also so gerade ausreichend.>> Solltest Du einen wesentlich schnelleren Prozessor haben, dann wirst Du> auch einen RTOS-Tick von 1ms oder was vergleichbares haben. Dann einfach> an im Interrupt (egal ob schon an oder nicht) und Aus im Ticker (egal ob> schon aus oder nicht).>> Beim Senden ist es einfacher, da kann man quasi einfach dann abschalten,> wenn kein Zeichen mehr gesendet werden soll.
Blitzen lassen, das ist das Ziel. Siehe deine HDD LED, Netzwerk LED etc.
man erkennt ueberall ein aehnliches Arbeitsprinzip mal dimmt die LED
oder nach x Anzahl an Lese-/Schreibzugriffen blitzen sie kurz auf.
Was ist den eine High-Effizient LED?
Vor Routine einschalten und nach Routine ausschalten ist viel zu schnell
was muss die Anzahl an Bytes runterbrechen und die LED an-/ausschalten
Hallo,
du möchtest kein Dauerlicht während der Datenübertragung und du möchtest
die LED nicht mit dem USART Baudratentakt takten lassen, weil das zu
schnell ist? Korrekt? Sie soll sichtbar blinken möglichst unabhängig der
Baudrate? Korrekt
Dann hätte ich eine Idee. Du lässt schaltest sie am Begin der USART ISR
ein und am Ende wieder aus. Aber! Du lässt vorm einschalten noch einen
Vergleichswert überprüfen. Dieser Wert stellt den Blinktakt ein. Dieser
errechnet sich abhängig der Baudrate damit die LED immer langsam gleich
blinkt unabhängig der Baudrate.
Du kannst auch einen Timer je nach Baudrate setzen. Du musst nur
irgendwie den Anfang der Übertragung und Ende erkennen um ihn gezielt
ein- und wieder auszuschalten. Wie man das am dümmsten Macht unabhängig
für jede Art einer Datenübertragung, dafür habe ich keine wirkliche
Idee.
Hallo,
eine High-Effizient LED ist eine sehr helle Led die für schon gute
Helligkeit sehr sehr wenig Strom benötigt. Bszw. umgekehrt mit Standard
20mA so hell ist, dass du da nicht freiwillig reinschaust. Meistens sind
1mA und weniger ausreichend. Man muss nur bei der Auswahl darauf achten
welche zu verwenden die dennoch einen breiten Abstrahlwinkel haben. Mit
120° gibts genügend. Die ultra hyper hellen haben meistens nur 30° und
sind völlig ungeeignet. Meine ersten sind solche. Man sieht nur direkt
von vorn das sie leuchten. Das war ein Fehlkauf.
In deinem Fall willst du sie ja eh nicht direkt am USART Signal haben,
sonst sieht du nichts oder es kaum blitzen/blinken.
Ich habe mal sowas für einen RS485 Verteiler gebaut und dazu einfach die
RX und TX Leitungen, die ich anzeigen wollte, auf µC Pins mit PCINT
(Pin-Change-Interrupt) gelegt.
In der ISR prüfe ich dann, welcher Pin den Interrupt ausgelöst hat und
lasse die LED dann 30ms aufleuchten und mache sie anschließend für 30ms
wieder dunkel.
Interrupts, die während dieser Zeit dazukommen, tun dann einfach nix,
solange auf der LED noch eine "Blink-Phase" aktiv ist.
Das Ergebnis war dann angenehm ablesbar.
Hallo,
wegen dem langsamen blinken/blitzen nochmal länger drüber nachgedacht.
Macht das überhaupt Sinn? Das man es sieht müssen schon paar ms
vergehen. Nur kann eine kurze Übertragung in einem Bruchteil davon schon
vorbei sein. Dann würde die langsame Led entweder gar nicht reagieren
oder sie zeigt einen Zustand verzögert an der schon gar nicht mehr
vorhanden.
Guten Abend zusammen,
danke fuer alle Antworten, das Thema ist doch sehr interessant. Es gibt
Entwickler die diesen Code geschrieben haben und die mechanischen
Designer der "Datenuebertragungs-LED" viel Bedeutung in ihrer Arbeit
geschenkt haben mit gutem Grund - es ist nicht einfach. Wenn man es
genau beobachtet - an vielen USB Geraeten, RJ-45 Ports, Festplatten
aller Art (M2, SSD, HDD, etc.) werden sie alle mit dem gleichem
Algorithmys angesteuert (kurzes helles Aufleuchten bei geringen und
laengeres blitzen bei hoeheren Uebertragungsraten).
Veit D. schrieb:> Aber! Du lässt vorm einschalten noch einen> Vergleichswert überprüfen. Dieser Wert stellt den Blinktakt ein. Dieser> errechnet sich abhängig der Baudrate damit die LED immer langsam gleich> blinkt unabhängig der Baudrate.
Genau in diese Richtung geht es! Im Endeffekt haben wir einen Code den
jeder sich individuell fuer seine Baudrate verwenden kann!
Veit D. schrieb:> Du kannst auch einen Timer je nach Baudrate setzen.
Ein Timer dazu zu opfern ist zu schade bzw. geben die Umstaende es nicht
her. Eine LED "ohne Funktion" in einem komplexem Projekt blinken zu
lassen - ist fragwuerdig, das muss mit komplexen Schleifen
funktionieren.
Gerrit schrieb:> In der ISR prüfe ich dann, welcher Pin den Interrupt ausgelöst hat und> lasse die LED dann 30ms aufleuchten und mache sie anschließend für 30ms> wieder dunkel.> Interrupts, die während dieser Zeit dazukommen, tun dann einfach nix,> solange auf der LED noch eine "Blink-Phase" aktiv ist.
Kostet Hardwareressourcen - wir behalten uns diesen Loesungsvoranschlag
im Hinterkopf.
Veit D. schrieb:> Das man es sieht müssen schon paar ms> vergehen. Nur kann eine kurze Übertragung in einem Bruchteil davon schon> vorbei sein. Dann würde die langsame Led entweder gar nicht reagieren> oder sie zeigt einen Zustand verzögert an der schon gar nicht mehr> vorhanden.
Richtig. Deswegen bringt das Ein- und Ausschalten vor und nach der
Routine keinen bedeutenden Effekt. Auch die paralleldiode hilft nicht
weiter da wir mit Gleichspannung arbeiten sowie High efficient LED´s
(die Ausgangsfrequenz geben wir Codeseitig vor, was die LED an Strom
benoetigt um Photonen auszustrahlen damit wir sie sehen === falsches
Thema)
Das menschliche Auge nimmt frequentierende An-/Auszustaende ab 50Hz
(20ms) nicht mehr wahr (Dauerleuchten).
Der Code sollte also in Abhaengigkeit der Baudrate periodisch einen
Ausgang ein- und abschalten.
von BaeumeKommunizierenElektromagnetisch schrieb:> Der Code sollte also in Abhaengigkeit der Baudrate periodisch einen> Ausgang ein- und abschalten.
In Abhängigkeit der baudrate? Seid ihr euch da sicher?
Dass der Code mangels Endekennung (50% an) nicht sinnvoll ist, würde ja
direkt zu Anfang geschrieben.
Normalerweise will man etwas in Abhängigkeit der Daten, und da geht
einfach parallel zu den Daten sehr wohl. Habt ihr das schon Mal
ausprobiert?
Habt ihr einen Tick? 1ms? 10ms?
BaeumeKommunizierenElektromagnetisch schrieb:> habe ueber einen "schoen-zu-haben" nachgedacht was bei vielen> Kommunikationsschnittstellen zum Einsatz kommt - blitzende LED bei> Datenuebertragung.> Nun habe ich mich gefragt was die eleganteste/Rechenleistung beste> Variante waere eine LED blitzen zu lassen
Ganz allgemein wird dafür typischerweise eine Art Monoflop verwendet.
Feste Leuchtzeit, variable Pausenzeit (mit Untergrenze, aber ohne
Obergrenze).
Man braucht aber in jedem Fall irgendeine Zeitbasis, also einen Timer.
Der Monoflop wird vollständig durch diesen Timer betrieben, in Form
einer State-Machine. Die Kommunikationseinheit nimmt darauf nur insofern
Einfluss, als dass sie immer dann, wenn sie ein Byte transportiert hat,
ein Flag setzt.
Für mehrere Kommunikationskanäle (z.B. auch: TX und RX einer UART)
braucht man die Statemachine des Monoflop übrigens nur einmal
implementieren.
von BaeumeKommunizierenElektromagnetisch schrieb:> Ein Timer dazu zu opfern ist zu schade
Irgendeinen Timer mitbenutzen.
Es braucht nur zwei Variable (global und volatile).
Eine Variable anz enthält die Restanzahl Blinks. Initial 0.
Eine Variable zl zählt rückwärts, entspricht dem Zustand der LED.
Initial 0.
zlAn, zlAus sind zwei Konstanten, die das Puls-Pausenverhältnis
bestimmen:
Bei zl==zlAn wird die Led an, bei zl==zlAus ausgeschaltet, zlAn > zlAus.
Wenn Signal empfangen/gesendet anz auf z.B. 2 setzen.
Im Timer-Interrupt:
1
if(anz>0){
2
if(zl==0){
3
anz--
4
zl=zlAn
5
LEDan
6
}else{
7
zl--
8
if(zl==zlAus){
9
LEDaus
10
}
11
}
12
}
Angenommen der Interrupt wird jede ms aufgerufen:
Setzt man zlAn=200 und zlAus=150, die Led blitzt denn 5 mal pro sec
jeweils 0,05 sec.
von BaeumeKommunizierenElektromagnetisch schrieb:> Ein Timer dazu zu opfern ist zu schade bzw. geben die Umstaende es nicht
na ja, oft gibt es mehr als einen Timer.
Opfern ist ein starkes Wort weil Timer fast immer genutzt werden!
Im Timer IRQ kann man auch noch mal nebenbei einen Merker & oder Port
setzen um eine LED Blitzen zu lassen.
Solange es also UART Empfang oder Senden gibt muss ja nicht jedes Byte
eine LED blitzen lassen, das Blitzen muss auch gesehen werden also
ON/OFF haben, ist nach ON/OFF Timing immer noch Datenverkehr blitzt es
eben weiter, nur halt nicht nach jedem Byte wenn das schneller ist als
ON/OFF
Ich benutze sowas in meinen UsbUarts regelmäßig. Üblicherweise habe ich
immer einen Timer im ms Takt laufen, der das nebenbei eben miterledigt.
In der RX oder TX Routine setze ich dann einfach die Zeit und den Pin.
Den Pin setzr dann der Timer Interrupt einfach wieder zurück wenn die
Zeit abgelaufen ist. Die Zeit lässt sich so von 0 (Immer ein) bis 255ms
einstellen.
Joachim B. schrieb:> von BaeumeKommunizierenElektromagnetisch schrieb:>> Ein Timer dazu zu opfern ist zu schade bzw. geben die Umstaende es nicht> na ja, oft gibt es mehr als einen Timer.> Opfern ist ein starkes Wort weil Timer fast immer genutzt werden!> Im Timer IRQ kann man auch noch mal nebenbei einen Merker & oder Port> setzen um eine LED Blitzen zu lassen.
Erstens und zweitens das und drittens lassen sich viele
Peripherie-Einheiten als Timer missbrauchen, die eigentlich garnicht als
Timer gedacht sind. Im Prinzip alles, bei dem sich irgendwie ein Takt
einstellen läßt. Wenn's wirklich mal eng werden sollte mit den
designierten Timern...
Stefan ⛄ F. schrieb:> Led wie gehabt per Software einschalten und dann 50ms später> Timergesteuert wieder aus schalten. Dann sieht das so aus, wie an> Ethernet Routern.
Nicht ganz, da fehlt die Mindestpausenlänge, die Standard für das
LED-Geblinker von Ethernet-Equipment ist.
Die ergibt durchaus Sinn! Denk' mal drüber nach...
Hallo,
ich möchte noch einmal auf Dein Programm eingehen.
Du musst Dir vorher genau überlegen, was Du genau möchtest.
Soll Deine LED anzeigen, ob Daten bereit stehen, oder gerade übertragen
werden.
Möchtest Du ein Byte empfangen und gleich darauf reagieren, oder sollen
Zeichenketten übertragen werden, bis zum Zeichenketten Ende.
Wenn Du in der Interrupt Routine Register, die Du später anderweitig
nutzt, oder Flags änderst, sollten diese vorher gesichert werden.
push R16
in R16,SREG
push R16
;Dein Programm
pop R16
out SREG, R16
pop R16
reti
Nutzt Du das Register R31, verlierst Du das wertvolle Registerpaar Z.
Besser geeignet sind die Register R0 bis R15 oder das SRAM.
Die Zeilen
LED_OFF:
lds r24, UCSR0A ;bereit zum Epmfangen?
sbrs r24, RXC0
rjmp LED_OFF
brauchst Du nicht, weil das durch den INT geklärt ist.
Ein Zeichen ins SRAM kannst Du mit
lds R16, UDR0 ;Daten in Register R16 laden
sts Zeichen, R16
oder bei Zeichenketten mit
st X+, R16
schreiben.
Du siehst im Hauptprogramm durch den Zähler X, ob und wie viele Zeichen
übertragen wurden.
Du kannst die LED einschalten und nach der Verarbeitung in der
Hauptschleife ausschalten.
Gruß Carsten
Wenn Der TO nicht genau weiss, was er will, kann er ja mal einfach eine
LED an TX halten. In den meisten Fällen bieten die realen Telegramme ein
aussagekräftiges Muster. Das irgendwie zu analysieren und dann in 0-x
Herz zu transformieren ist meist vergebene Mühe mit deutlich geringerer
Aussagekraft.
Da der TO LEDs wohl eher nur theoretisch kennt, wird selbst das einfache
Dranhalten einer LED (für erste RL-Erfahrungen) nicht passieren.
A. S. schrieb:> Wenn Der TO nicht genau weiss, was er will
Also doch, das hat er im Eröffnungsposting doch dargestellt, er will
einen "traffic indicator". Er hat das nicht ganz so prägnant
ausgedrückt, aber man kann das dem hier
> was bei vielen> Kommunikationsschnittstellen zum Einsatz kommt - blitzende LED bei> Datenuebertragung.
doch durchaus als Anliegen entnehmen. Nur bei sehr viel bösem Willen
kann man das nicht...
c-hater schrieb:> Also doch, das hat er im Eröffnungsposting doch dargestellt, er will> einen "traffic indicator".
Du hast doch sicher schon einige serielle Schnittstellen mit LEDs
gesehen. Hast Du je was sinnvolleres als direkte LEDs gesehen? Wenn Du
anfängst Dir zu überlegen, wie du 50% mit 9.6 von 50% mit 115k
unterscheiden willst, dann wird das alles, nur nicht intuitiv.
Und wenn man Mal mit LEDs spielt, stellt man sehr schnell fest, dass man
auch einzelne Bytes sehen will und sehen kann.
Wie viele serielle Protokolle kennst Du aus der Praxis, die nicht
signifikante Pausen haben, die direkt viel aussagekräftiger sind, als
gefiltert.
Man will was authentisches, kein Disco-Code.
Nach den ersten 5 einfallslosen Posts habe ich nix weiterverfolgt.
Weil: Die Lösung ist doch pillepalle:
Jedes Programm mit zeitlichen Abläufen hat einen Systemtakt
(Timer-Interrupt) mit 0,5 ... 20 ms um die zeitlichen Abläufe,
wie Tasten-Drückzeit, Sensorabfragerate, ... zu beherrschen.
Nur dümmste Anfänger versuchen sich da mit delay()...
DANN weiß man aber schon mal, warum das Programm wohl nichts
taugt und kein Bisschen enwicklungsfähig ist...
Sobald ich was empfangen habe: LED ON und TimeOut = 255.
In der Systemtakt-Routine wird TimeOut dekrementiert und bei 0
erfolgt ein LED OFF.
Bei 0,5 ms-Takt ist die LED 1/8 Sekunde an, bei 20 ms etwa
5 s. Bei 20 ms-Takt könnte man mit TimeOut = 25 für sinn-
fälligere 0,5 s sorgen.
Das Auge bekommt Aktivitäten mit - mehr will man doch nicht!
Beim Senden geht das genauso.
Hat jemand eine (simple!) einleuchtendere Idee?
Schwer vorstellbar...
A. S. schrieb:> Du hast doch sicher schon einige serielle Schnittstellen mit LEDs> gesehen.
Aber sicher.
> Hast Du je was sinnvolleres als direkte LEDs gesehen?
Aber sicher.
> anfängst Dir zu überlegen, wie du 50% mit 9.6 von 50% mit 115k> unterscheiden willst, dann wird das alles, nur nicht intuitiv.
Bei einem Traffic-Indicator geht es nicht darum, dem Eingeweihten intime
Details der Kommunikation zu verraten. Es geht darum, dem Laien
möglichst unübersehbar zu sagen: hier passiert was (oder halt auch
nicht).
Das Konzept wird umso sinnvoller, je schneller die Kommunikation
erfolgt. Selbst dir wird es schon schwer fallen, ein einzelnes Byte mit
einem einzigen gesetzten Bit auf einer 1Mbit-Strecke in seiner direkten
LED-Abbildung zu erkennen. Und 1MBit ist selbst mit den schwächlichen
AVR8 ja heute keine sehr unübliche Anwendung mehr.
Von I2C (immerhin bis 400kHz), SPI, USB usw. mal ganz zu schweigen.
Du musst die Sache einfach mal umfassender betrachten und nicht auf das
bissel Pillepalle von vor 20 Jahren beschränken.
Der Witz ist übrigens: auch sowas kann man mit dem "Indikator-Konzept"
immer noch recht gut verfolgen...
Probier es einfach mal aus...
>Teste es auf einem ATMega328P
also Arduino möglich -> RTOS möglich
RTOS Lib unter Arduino installieren, Beispiel Code von Blink_AnalogRead
anschauen und auf UART ummünzen
leicht wartbar und erweiterbar wenn das Projekt wächst.
Assembler kann man verwenden, muss man aber nicht.
Und für die Noobs in Sachen RTOS, delay() != RTOS delay()
Carsten schrieb:> Nutzt Du das Register R31, verlierst Du das wertvolle Registerpaar Z.
Danke, ist bereits bekannt war fuer dieses Beispiel angesetzt.
A. S. schrieb:> Da der TO LEDs wohl eher nur theoretisch kennt, wird selbst das einfache> Dranhalten einer LED (für erste RL-Erfahrungen) nicht passieren.
Ich enthalte mich hier besser. Halt mal eine LED da dran. Ohne es zu
Testen weiss man doch was passiert?!?!?!
Danke Dir C-Hater, Du bist in Ordnung.
Habe es nun geloest, Vorteiler steht auf 8 bei 8Mhz. Man muss den Teil
sich fuer seinen Timervorteiler anpassen. Das Problem das die LED an
sein koennte wenn die Interruptroutine beendet wird habe ich in der
Timeroverflowroutine geloest. Das Ergebnis gefaellt mir wie erwartet.
Bevor wieder draufgegangen wird wie Frischfleisch es dient zum
Verstaendnis und nicht als C&P Vorlage, danke fuer euer Verstaendnis:
1
T0Overflow:
2
ldi r31, 'R' ;Der Hauptteil in der Routine, hier Daten senden
3
sts UDR0, r31
4
inc r29
5
cpi r29, 3 ;Dieses Register nutzen wir aus um die LED abzuschalten nachdem sie eventuell an ist
6
brne ende
7
clr r29
8
ldi r18, 0x00 ;Als ganzen Port, diesen Teil anpassen um nur den jeweiligen Bit zu manipulieren