Forum: Mikrocontroller und Digitale Elektronik Mehrere Zufallsgeneratoren an verschiedenen PWM Ausgängen


von Nur geklaut (Gast)


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

von Jim M. (turboj)


Lesenswert?

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

von Wolfgang (Gast)


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.

von Nur geklaut (Gast)


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?

von Nur geklaut (Gast)


Lesenswert?

Nur geklaut schrieb:
> Wolfang

Das erste g wollte leider nicht mit ;)

von Falk B. (falk)


Lesenswert?

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.

von EAF (Gast)


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
}

von EAF (Gast)


Lesenswert?

Nachtrag: (der Konstruktor sollte evtl so aussehen)
PWMmacher(const byte pin):pin{pin},interval{0}{}

von Da Baby (Gast)


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.

von Jobst M. (jobstens-de)


Lesenswert?

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

von Nur geklaut (Gast)


Lesenswert?

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 ;)

von Da Baby (Gast)


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

von EAF (Gast)


Lesenswert?

Ach....


Eigentlich wollte ich diesen Zustand
> Bei mir flimmert es nur dunkel im Kopf
etwas optimieren.
Quasi das Maximum raus holen.

von Wolfgang (Gast)


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.

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
Noch kein Account? Hier anmelden.