Mehrere Zufallsgeneratoren an verschiedenen PWM Ausgängen

Gast #7330290
Lesenswert?

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

Gast #7330303
Lesenswert?

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.

Gast #7330310
Lesenswert?

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?

Gast #7330320
Lesenswert?

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
}
Gast #7330323
Lesenswert?

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.

Gast #7330352
Lesenswert?

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++

Gast #7330367
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren