Guten Abend euch. Bei meinem kleinen Projekt dachte ich, dass ich nicht auf Probleme stoße, aber dann kam es doch dazu und meine Experimente schlugen alle fehl. Ich habe einen Attiny44a mit 4 PWM Aushängen, die ich alle mit jeweils einer LED belegt habe. Das soll nur ein kleines Programm für 4 "Kerzen" sein. Ich möchte aber bei jeder Kerze einen anderen Zufallsgenerator haben, also Helligkeit und Intervall einstellen. Das Grundprogramm habe ich nur geklaut und etwas angepasst: int LED1 = 8; int LED2 = 7; int LED3 = 6; int LED4 = 5; int val = 0; // variable Helligkeit int delayval = 0; // variable Wartezeit void setup() { randomSeed(0); // Zufallszahlengenerator pinMode(LED1, OUTPUT); pinMode(LED2, OUTPUT); pinMode(LED3, OUTPUT); pinMode(LED4, OUTPUT); } void loop() { val = random(70, 200); analogWrite(LED1, val); val = random(40, 255); analogWrite(LED2, val); val = random(100, 230); analogWrite(LED3, val); val = random(10, 190); analogWrite(LED4, val); delayval = random(250, 800); delay(delayval); } Nun ist mir schon klar, dass mein Intervall der Wartezeit so auf alle 4 LEDs zutrifft. Aber ich habe es nicht hinbekommen, dass ich für jede LED ein eigenes Intervall bekomme. Also z.B. LED1 flimmert durchgehend sehr langsam (100, 250), LED2 durchgehend sehr schnell (600, 800) usw.. Bei mir flimmert es nur dunkel im Kopf... ich befürchte, das ist ein ganz simples Ding. Oder ist das wieder ein typisches "das geht nicht mit delay"? Ich bedanke mich für Lösungen,Anregungen und Schimpfe ;) Schöne Grüße
Nur geklaut schrieb: > Aber ich habe es nicht hinbekommen, dass ich für jede LED > ein eigenes Intervall bekomme Wieso eigentlich nicht? Ein Zähler + etwas Modulo Artithmetik pro LED. Idee ist das nicht jede LED bei jedem Delay geändert wird sondern nur bei jedem 2. oder 3. oder ähnlich...
Nur geklaut schrieb: > Oder ist das wieder ein typisches "das geht nicht mit > delay"? Richtig, du solltest nicht mit einem gemeinsamen, zufälligen Delay arbeiten. Nimm ein festes, kurzes delay() oder werte besser mit millis() den Millisekundentaktgeber aus. Wie häufig eine LED ihren Zustand ändert, legst du dann mit einem für jede LED persönlich zugeordneten Zähler zufällig fest.
Danke euch Beiden. Von Jim verstehe ich leider gar nichts, das ist mir ne Nummer zu hoch. Das was Wolfang hört sich schon einfacher an, aber es war auch meine Befürchtung. Mit millis habe ich noch nie rumgespielt, wird dann wohl viel zu lesen. Gibt es gute Tutorials auf Deutsch?
Nur geklaut schrieb: > mir flimmert es nur dunkel im Kopf... ich befürchte, das ist ein ganz > simples Ding. Oder ist das wieder ein typisches "das geht nicht mit > delay"? BINGO! DU bist der 735503635te, der das Thema Multitasking entdeckt. Beitrag "Re: 20 LEDs unterschiedlich blinken lassen" Dort kann man auch live Zufallszahlen füttern.
Nur geklaut schrieb: > das ist mir ne Nummer zu hoch. Ja, das kann ich dir bieten!
1 | |
2 | class SimpleTimer |
3 | {
|
4 | private:
|
5 | uint32_t timeStamp; // Zeitmerker |
6 | bool reached; // default Status: timer abgelaufen |
7 | |
8 | public:
|
9 | SimpleTimer():timeStamp(0),reached(true){} |
10 | |
11 | void start() |
12 | {
|
13 | timeStamp = millis(); |
14 | reached = false; |
15 | }
|
16 | |
17 | void reset() |
18 | {
|
19 | reached = true; |
20 | }
|
21 | |
22 | bool operator()(const uint32_t interval) |
23 | {
|
24 | if(!reached) reached = millis() - timeStamp >= interval; |
25 | return reached; |
26 | }
|
27 | };
|
28 | |
29 | |
30 | class PWMmacher |
31 | {
|
32 | private:
|
33 | const byte pin; |
34 | unsigned long interval; |
35 | SimpleTimer timer; |
36 | |
37 | public:
|
38 | PWMmacher(const byte pin):pin{pin}{} |
39 | void run() |
40 | {
|
41 | if(timer(interval)) |
42 | {
|
43 | timer.start(); |
44 | interval = random(400,3000); |
45 | analogWrite(pin,random(0,256)); |
46 | }
|
47 | }
|
48 | };
|
49 | |
50 | PWMmacher pwm[]{3,5,6,9,10,11,};// UNO pwm pins |
51 | |
52 | void setup() {} |
53 | |
54 | void loop() |
55 | {
|
56 | for(auto &p:pwm)p.run(); |
57 | }
|
Nachtrag: (der Konstruktor sollte evtl so aussehen) PWMmacher(const byte pin):pin{pin},interval{0}{}
Nimm einen Timer und stelle die Frequenz so ein, dass ein Überlauf der obersten Intervallgrenze entspricht. Pro Takt wird der Zähler um eins hochgezählt. Dann rätst du 4 Zufallszahlen und aktivierst je nach Zählerstand eine der vier LEDs. Danach kannst du das selbe machen um die LEDs wieder auszuschalten.
Nur geklaut schrieb: > Wartezeit Wieso meinst Du, dass Du die zufälligen Helligkeitswerte mit zufälligen Zeiten takten musst? Du benötigst einen Tiefpass, sonst wirkt das immer etwas hektisch. Gruß Jobst
Danke allen! Ich nehme mir das zu Herzen und gehe es morgen mal alles in Ruhe durch. Das ist für mich zwar viel Fachchinesisch, aber die paar Tipps lassen mich dann auch besser googlen ;)
Nur geklaut schrieb: > Danke allen! Ich nehme mir das zu Herzen und gehe es morgen mal > alles in > Ruhe durch. Das ist für mich zwar viel Fachchinesisch, aber die paar > Tipps lassen mich dann auch besser googlen ;) Im Grunde musst du nur das von EAF kopieren. Das ist eine fertig Lösung. Nur eben in C++
Ach....
Eigentlich wollte ich diesen Zustand
> Bei mir flimmert es nur dunkel im Kopf
etwas optimieren.
Quasi das Maximum raus holen.
Da Baby schrieb: > Im Grunde musst du nur das von EAF kopieren. Das ist eine fertig Lösung. Eher nicht. An Stelle der direkten Ausgabe von Zufallszahl mit analogWrite() ist es schon ratsam, die Werte erstmal durch ein digitales Tiefpassfilter laufen zu lassen und erst die geglätteten Werte zur Steuerung der Ausgangs-PWM zu verwenden. Jobst M. schrieb: > Du benötigst einen Tiefpass, sonst wirkt das immer etwas hektisch.
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.