Hallo,
ich versuche schon eine ganze Weile für folgende Aufgabenstellung eine
Lösung zu finden, ohne dabei an die Kapaztätsgrenzen des ATTiny2313 zu
kommen.
An diesen µC sollen oder sind 15 LEDs angeschlossen, die in einem Kreis
angeordnet sind. Von diesen LEDs sollen immer 3, jeweils zur gleichen
Zeit an sein. Nun sollen die LEDs, ähnlich einem Leuchtturm eine
Rotationsbewegung vollziehen. Soweit kein Problem, und wohl der
leichteste Teil der Aufgabe.
Die Startbedingungen sind Drehrichtung rechts, Anzeit bis zur
Weiterschaltung auf die nächste LED Gruppe 1000ms.
Bisher habe ich den Gedankenansatz verfolgt, die Pindefinition in C über
ein Array zu machen, damit ich über eine For() Schleife von 0 bis 4
zählen eine vollständige Drehbewegung darstellen kann.
Das mal als Auszug zum bisherigen Programm.
Nun würde ich gerne das Programm um folgende Funktion, die durch einen
ALPS STEC12 umgesetzt wird, ergänzen wollen:
Grundsätzlich gleich noch folgende Angabe dazu es handelt sich um eine
gelegendliche Handeineingabe, der Encoder muss somit nicht zwingend via
Polling ständig abgefragt werden.
Ausgehend von der Startbedingung Rechtsdrehung, und einer
Verzögerungszeit = is_Time soll num bei einer Encoderdrehung nach rechts
die is_Time um jeweils Time_Step bis Time_Min verringert werden. Alles
was darüber hinaus geht soll ignoriert werden. Dreht man nun den
Encoder-Knopf nach links, erhöht sich die is_Time bis zum Werte von
Time_Max. Und nun kommt der Überschlag. Dreht man noch eine Raste
weiter, soll die Drehbewegung gestoppt werden. Und noch eine Raste
weiter nach links, soll eine Richtungsänderung stattfinden. Dabei ist
is_Time immer noch Time_Max. Bei einem weiterdrehen am Encoder-Knopf
nach links soll nun pro Rate is_Time um jeweils Time_Step verringert
werden.
Das bekomme ich auch noch mit Polling hin.
Hier fehlt jedoch noch ein Taster. Dazu müsste ich das Reset-PIN
wegfusen.
Bei einem Tastendruck, soll die dargestellte Drehbewegung angehalten,
und bei einem erneuten fortgesetzt wrden.
Jetzt die Große Frae zu dem ganzen Projekt, wie setzt man das am
elegantesten um ? Nutzt man Interripts zur Encode- und Taster Abfrage ?
Bekommt man damit den Speicherverbrauch besser in den Griff, oder muss
man hier nun womöglich auf Assembler zurückgreifen ?
Im Voraus schon mal Danke für alle Antworten, und beste Grüße
Andreas
> gelegendliche Handeineingabe, der Encoder muss somit nicht zwingend via> Polling ständig abgefragt werden.
Doch das muss. Wenn du anderer Meinung bist hast du die Theorie dahinter
noch nicht verstanden.
> Jetzt die Große Frae zu dem ganzen Projekt, wie setzt man das am> elegantesten um ?
Indem du einen TimerIRQ aufsetzt der die Abfrage fuer dich macht.
Ueberleg dir wie schnell du maximal drehen willst, wieviele Impulse das
pro Sekunde gibt, multipliziere das noch mit 4 und du weisst wie schnell
dein Timer laufen muss.
Olaf
Andreas G. schrieb:> Bekommt man damit den Speicherverbrauch besser in den Griff, oder muss> man hier nun womöglich auf Assembler zurückgreifen ?
Welcher Speicher denn?
Ich sehe da nichts kritisches.
Man kann nicht erkennen, wie groß "PINs[]" ist. Besser daher das
compilierbare Programm als Anhang.
"PINs[]" könnte man in den Flash legen, da konstant.
"int" verdoppelt schonmal den RAM-Verbrauch. Wenn 0..255 reicht, nimmt
man besser "uint8_t".
Andreas G. schrieb:> An diesen µC sollen oder sind 15 LEDs angeschlossen, die in einem Kreis> angeordnet sind. Von diesen LEDs sollen immer 3, jeweils zur gleichen> Zeit an sein. Nun sollen die LEDs, ähnlich einem Leuchtturm eine> Rotationsbewegung vollziehen.> Bisher habe ich den Gedankenansatz verfolgt, die Pindefinition in C über> ein Array zu machen, damit ich über eine For() Schleife von 0 bis 4> zählen eine vollständige Drehbewegung darstellen kann.
Bei 15 LEDs hätte ich eine for()-Schleife von 0 bis 14 erwartet. Bei
einem Leuchtturm läuft der Lichtkegel gleichmäßig durch, egal wie breit
der Sektor ist. Der spring nicht um Sektorbreiten.
Wolfgang schrieb:> Bei 15 LEDs hätte ich eine for()-Schleife von 0 bis 14 erwartet.
Man könnte auch ein uint16_t nehmen und rotieren.
Wenn man dann die LEDs gleich richtig an PB und PD anschließt, wird das
Programm besonders kurz und SRAM-sparend.
Wolfgang schrieb:> Bei 15 LEDs hätte ich eine for()-Schleife von 0 bis 14 erwartet. Bei> einem Leuchtturm läuft der Lichtkegel gleichmäßig durch, egal wie breit> der Sektor ist. Der spring nicht um Sektorbreiten.
Ist es nicht vom Programmlauf egal ob ich
1
for(inti=0;i<=14;i++){}
oder
1
for(inti=0;i<15;i++){}
zumindest bei mir ist das Ergebnis immer das gleich. Es wird von 0 bis
14 gezählt.
Hat das eine hintergründige Relevanz, wenn ich damit ein Arrray
anspreche ?
Peter D. schrieb:> Wolfgang schrieb:>> Bei 15 LEDs hätte ich eine for()-Schleife von 0 bis 14 erwartet.>> Man könnte auch ein uint16_t nehmen und rotieren.> Wenn man dann die LEDs gleich richtig an PB und PD anschließt, wird das> Programm besonders kurz und SRAM-sparend.uint16_t pattern:> void rotate(void)> {> pattern <<= 1;> PORTB = pattern;> PORTD = pattern >> 8;> }
Da rotiert aber nix. Die Shift-Operation in C wird NICHT zirkulär
vollzogen.
Falk B. schrieb:> Wenn von den 15 LEDs max. 3 gleichzeitig leuchten soll, würde ich> Charliplexing nutzen.>> https://www.mikrocontroller.net/articles/LED-Matrix#Charlieplexing
Danke für den Hinweis. Da es das Thema Integration eines Rotary Encoders
und eines Interrupt-abgefragten Tasters nicht wirklich trifft, hier noch
der *allgemeine Hinweis*:
Die Enscheidung für den Tiny2313 SOIC erfolgte in erste Linie aus
Platzgründen.
Auf einer Platine die nicht größer als 22x43 mm sein darf, habe ich
keinen Platz mehr für zusätzliche Schaltkreise, Leiterbahnen und
Treibertransistoren.
Hallo,
danke noch einmal das sich hier so viele Leute auf diesen Beitrag
gemeldet haben.
Um der Verwirrung, die hier wohl mit der Nutzng der PLATTERN aufgetaucht
ist mal ein Ende zu bereiten:
- 15 LEDs in der Summe.
- immer 3 LEDs leuchten Zeitgleich
- ein Aus für alle gibt es nicht
- Anhand der Darstellung von Wolfgang:
1
Schritt 0
2
Reihe 1 | *----
3
Reihe 2 | *----
4
Reihe 3 | *----
5
Schritt 1
6
Reihe 1 | -*---
7
Reihe 2 | -*---
8
Reihe 3 | -*---
9
Schritt 2
10
Reihe 1 | --*--
11
Reihe 2 | --*--
12
Reihe 3 | --*--
13
Schritt 3
14
Reihe 1 | ---*-
15
Reihe 2 | ---*-
16
Reihe 3 | ---*-
17
Schritt 4
18
Reihe 1 | ----*
19
Reihe 2 | ----*
20
Reihe 3 | ----*
Das heißt, der eigentlich Ablauf beschränkt sich auf 5 Schritte, und die
Aufteilung kann über einfaches addieren +5 und +10 stattfimden, falls es
bei der Grunddefinition der Port-Pins in einem Array bleibt.
Andreas G. schrieb:> Das heißt, der eigentlich Ablauf beschränkt sich auf 5 Schritte ...
Versteh' ich nicht, wieso dann eine Schleife mit 15 Durchläufen?
72°-Sprünge macht kein klassischer Leuchtturm - der Kegel läuft dort
schön gleichmäßig um.
Andreas G. schrieb:> Danke für den Hinweis.> Der Versuch diesen Entwurf zu einem Programm für einen ATTiny2313 daraus> zu machen, scheitet am Resourcenbedarf, sowie die benötigte> Speichergröße Programmflash wie auch bei der Variablenbelegung RAM.
Dann machst du mehrere Fehler. Wenn gleich der Tiny2313 nur 2kB Flash
hat, bekommt man deine Funktion dort rein, wenn man weiß was man tut.
Mit welcher Umgebung programmierst du? pinMode deutet auf Arduino hin.
Das ist zwar etwas bequemer, frißt aber sinnlose Resourcen. Man sollte
mit einfachem C und avr gcc arbeiten, das ist bei so einem kleinen
COntroller problemlos.
Man kann die übliche Encoderauswertung von der üblichen Echtzeittakt-ISR
pollen oder auch von einer modifizierten Busy-Warteroutine in der
Hauptschleife wie
Hallo,
Für alle die jetzt ein Problem mit der 15, den 3 Paaren, und einem
Vollkreis von 360 Grad haben.
- 15 LEDs verteilt auf 360 Grad = ca. 24 Grad Abstand zwischen den LEDS
( ca. nur deshalb, weil es nicht 100 % genau auf der Leiterplatte geht,
aber schlussendlich nicht wirklich funktions relevant )
- immer 3 LEDs bilden ein Paar -> somit sendet der virtuell als
Gedankenstütze gedachte "Leuchtturm" immer 3 Strahlen gleichzeitig aus,
wobei der Versatz zwischen den eingeschalteten LEDs immer 4 LEDs beträt,
die zeitgleich nicht leuchten.
Die For() Schleife mit 15 Durchläufen nutzen ich in meinem bisherigen
Programm, welches schon zT eim Eingangspost veröffentlicht wurde nur um
die Initiierung der Port-Pins durchzuführen.
@Falk
Wow.
bis auf wohl einen Übertragungsfehler in Zeile 114
1
int8_tnew,diff,tmp;
wo ich das "new", sowie in den Folgezeilen durch ein "neu" ersetzt habe,
ist das Programm wirklich ein winzling.
Nun auf in den Elektronikshop des Vertrauens, und eine Lochrasterplatte
für den ersten Versuchsaufbau besorgt.
Andreas G. schrieb:> - immer 3 LEDs bilden ein Paar -> somit sendet der virtuell als
Drei sind nie ein Paar, bestenfalls eine Gruppe. Ein Paar sind immer 2.
> bis auf wohl einen Übertragungsfehler in Zeile 114int8_t new, diff, tmp;> wo ich das "new", sowie in den Folgezeilen durch ein "neu" ersetzt habe,> ist das Programm wirklich ein winzling.
Muss man nicht. In C darf man new als Variablenname verwenden, das ist
kein reserviertes Wort. In C++ ist das anders.
Hallo, und Danke
besonders Falk B. hat gezeigt, dass mit einer umfassenden Kenntnis der
Programmiermöglichkeiten, man doch mehr machen kann, als was hier von
einigen als Meinung vertreten wird.
Der Vorschlag und das Beispiel von ihm hat gezeigt, dass für einige und
noch benötigte Erweiterungen noch genögend Flsh-Speicher vorhanden ist.
Nach den ersten Versuchen mit der vorgestellten Schaltung und kleinen
Änderungen an dem dazugehörigen Programm, haben sich meine Befürchtungen
bewahrheitet, dass mit Low-Power LEDs diese Schaltung zweifelsfrei
funktioniert, und sich auf dem mir zur Verfügung stehenden Platzgebot
für eine Leiterplatte umsetzen lässt. Danke nochmals an Falk.
Jetzt muss ich mir erneute Gedanken machen, wie ich das nun auseinander
frickle. Der ursprüngliche Plan, die schon entworfene Schaltung später
dort MOSFET gesteuerte Power LED mit bis zu 150 mA pro LED nutzen zu
wollen, geht mit Charliplexing auf der mir zur Verfügung stehenden
Maximalgröße der Platine nicht. Für dem AVR 2313 hatte ich enen MCP1804
Festspannungsregler 150mA SOT-23 mit Minimalbeschaltung ( zwei 1µF SMD
Kerko ) vorgesehen.
Andreas
Andreas G. schrieb:> Jetzt muss ich mir erneute Gedanken machen, wie ich das nun auseinander> frickle. Der ursprüngliche Plan, die schon entworfene Schaltung später> dort MOSFET gesteuerte Power LED mit bis zu 150 mA pro LED nutzen zu> wollen, geht mit Charliplexing auf der mir zur Verfügung stehenden> Maximalgröße der Platine nicht.
150mA LEDs? Soll das ein Scheinwerfer werden? Nimm ultrahelle LEDs, die
blenden auch bei 2mA. Du kannst auch die Widerstände kleiner machen oder
gar ganz weglassen, die Ausgangswiderstände des AVR von ca. 30 Ohm
begrenzen dann den Strom. Man kann auch Platz sparen, indem man einen
etwas kleineren AVR nimmt, z.B. ATtiny24 in SOIC14, nochmal deutlich
kleiner als der 2313 und trotzdem noch human lötbar. Wenn's eng wird,
nimm den im QFN20 Gehäuse mit 4x4mm ;-)
Hallo Falk B.,
Ja, es geht um Beleuchtungszwecke. Und entschuldige bitte meine
verspätete Rückmeldung.
Die kleinerewn Super-hellen LEDs sind für den Prototypen Aufbau durchaus
ganz brauchbar.
Nur haben erste Versuche in den Einsatzbedingungen Nacht gezeigt, das
der Abstrahlwinkel dieser kleinen LEDs nicht ausreichen, um diese sowohl
in der horizontalen Ebene wie auch von oben aus größeren Entfernungen
erkennen zu können.
Von oben mit einer Drohne betrachtet aus etwa 15 Meter Flughöhe ist das
nur noch ein einziger "Farbbrei" ;) der keine klare Zuordnung der
Richtungsvektoren mehr zulässt, wenn diese in der Ebene breit
ausstrahlen. Nach oben gerichtete LEDs erkennt man vom Boden aus auch
nur noch auf etwa 30 Meter. Das es den 2313 auch in SMD SOIC-20 gibt war
schon in der Planung angedacht.
Dahingehend haben schon erste Tests gezeigt, dass Power LEDs mit einem
größeren Absteahlwinkel von ca. 60 Grad, angeordnet und angestellt auf
der Aussenfläche eines Kegelstumpfes mit 45 Grad Neigung auch aus
größeren Höhen, und in der Ebene aus über 100 Meter sicher erkannt
werden können.
Jetzt auf mehrere LEDS in unterschiedlichen Abstrahlwinkeln ( Horizontal
bis Vertikal) zu setzen, bringt mich mit Charlieplexing auch nicht
weiter.
Die LED Anordnung ist selber nicht das Problem. Die erfolgt angesetzt
via Kabelverbindung mit der Steuereinheit. Auch das eigentliche händisch
bediente Steuerelement, der Rotary Encoder muss auf der
Controllerplatine keinen Platz finden. Auch dieser soll via Kabel mit
der Controllerplatine verbunden werden.
Konstruktiv um alles auf der zur Vefügung stehenden Fläche
unterzubringen, befindet sich auf der Oberseite nur der 2313 und ein
MCP1804 mit den beiden Kerkos, und den notwendigen Durchkontaktierungen.
Auf der Unterseite ein MCP1726 für die LEDs mit Aussenbeschaltung, den
15 NMOS (250mA) in SOT323 mit Vorwiderständen und den
Durchkontaktierungen zu den PINs den 2313. Die LEDs werden nur über
platzsparende Lötflächen ohne Durchkontaktierung ausgeführt. Also
Oberseite nur der ATTiny mit Stromversorung und den Lötflächen für den
Rot-Encoder, und der Spannungszuführung, und auf der Rückseite nur das
Leistungsteil zur Ansteuerung der LEDs. Wobei hier noch 15 der ATTiny
Pins jeweile eine einzige LED Treiberstufe ansteuern.
Gruß
Andreas G. schrieb:> Nun würde ich gerne das Programm um folgende Funktion, die durch einen> ALPS STEC12 umgesetzt wird, ergänzen wollen
Halte erst mal die verschiedenen Dinge auseinander.
Du hast:
- eine Art Systemuhr, die dir die verschiedenen Leucht-Zeiten usw. macht
- einen Algorithmus, der in Abhängigkeit von den Zeitsignalen deiner
Systemuhr deinen "Leuchtturm" weiterschaltet
Und jetzt willst du noch dazu haben:
- einen Treiber, der aus den Signalen eines eventuell angeschlossenen
Drehgebers Kommandos (nach rechts, nach links) macht
- ein Kommandoprogramm, das die gegebenen Kommandos auswertet und damit
die E/A-Zeit-Vorgaben deiner Systemuhr oder die Eckdaten deines
"Leuchtturmes" ändert.
Schreib dir erstmal deinen Treiber, damit du zu den Kommandos "rechts"
oder "Links" kommst. Wenn das funktioniert, dann kannst du dich an das
Kommandoprogramm machen. Und denke daran, daß man einen Drehgeber sowohl
entprellen sollte, als auch sich entscheiden muß, ob man ihn nun pollen
will oder mit Interrupts arbeiten will. Ich selber mache das eigentlich
immer per Interrupt, aber hier tummeln sich recht viele Leute, die
sich da lieber auf's Pollen verlegen, und denen der Aufwand an
Rechenzeit für sowas einfach schnurz ist.
W.S.