LEDs Radom ansteuern (wie Würfel, aber mit verschiedenen Wahrscheinlichkeiten)

Servus Beinander,

bin noch recht neu im Arduino Programmieren, brauch eure hilfe um ein Projekt zu realisieren.
Bei Vorschlängen für die Umsetzung wäre ich euch dankbar wenn ihr mit Beispielen arbeitet, da ich mich noch schwer tue mit dem Programmiercode.

Was will ich machen:
Ich möchte zwei LED random leuchten lassen, aber in verschieden Wahrscheinlichkeiten.
Dazu habe ich einen Drehschalter (mit vier Positionen) und zwei Taster.

Wärend des Tastendrucks des Starttaster soll die grüne und rote LED abwechselnd leuchten.

Nach Tastendruck soll bei...
Position 1 soll die grüne LED immer leuchten 100%.
Position 2 soll die grüne LED nur in 80% der Fälle leuchten (ansonst die rote LED).
Position 3 soll die grüne LED nur in 60% der Fälle leuchten (ansonst die rote LED).
Position 4 soll nur die rote LED leuchten.

Bei Drücken des Resttasters, soll entwerder keine LED leuchten oder beide.

Wie kann ich am besten die Randomzahlen dazu erzeugen?
Wie die Abfrage des Drehschalters machen (mit IF und OR oder lieber ELSE Befehle) um damit je nach Position einen anderes Programm (Wahrscheinlichkeiten) dazu laufen lassen.

viele Dank
Sepp

Für die Taster baust du dir erst mal ein Konstrukt aus lauter IFs um die einzelnen Modi zu setzen.
Das geht in die Such-Richtung Endlicher Automat / Zustandsautomat.
Die Modi lässt du dir per Serial ausgeben.
Danach gehts an die LEDs.

Viking77:
Wärend des Tastendrucks des Starttaster soll die grüne und rote LED abwechselnd leuchten.

Das machst Du am besten mit einer while()-Konstruktion, etwa so:

while(digitalRead(Tasterpin)==LOW)
{
  // Code zum Blinken
}

Viking77:
Nach Tastendruck soll bei...
Position 1 soll die grüne LED immer leuchten 100%.
Position 2 soll die grüne LED nur in 80% der Fälle leuchten (ansonst die rote LED).
Position 3 soll die grüne LED nur in 60% der Fälle leuchten (ansonst die rote LED).
Position 4 soll nur die rote LED leuchten.

Die Zufallszahlen erzeugst Du beispielsweise mit

zahl=random(10);

und prüfst dann, ob die Zahl kleiner als 8 (für 80%) oder 6 (für 60%) ist.

Viking77:
Wie kann ich am besten die Randomzahlen dazu erzeugen?

Mit random().

Viking77:
Wie die Abfrage des Drehschalters machen (mit IF und OR oder lieber ELSE Befehle) um damit je nach Position einen anderes Programm (Wahrscheinlichkeiten) dazu laufen lassen.

Taster/Schalter und dergleichen schließt man so an einen Arduino-Pin an, dass der Pin durch den Taster oder Schalter mit GND verbunden wird. Den Pin initialisierst Du in setup() mit

pinMode(Tasterpin, INPUT_PULLUP);

Dadurch ist der Pin bei nicht betätigtem Taster auf jeden Fall HIGH. Um zu gucken, ob der Taster gedrückt bzw. ob der Schalter in der entsprechenden Position ist, prüfst Du dann, ob ein digitalRead(Tasterpin) LOW ergibt.

Gruß

Gregor

PS: Da das Stichwort endlicher Automat gefallen ist: Vor ein paar Monaten habe ich hierzu das hier ins Netz gekippt. Vielleicht hift das.

Wie kann ich am besten die Randomzahlen dazu erzeugen?

Für die 80 % Wahrscheinlichkeit z.B. so:

if (random(10) < 8) {...}

Da das nur Pseudozufallszahlen erzeugt, sollte man RandomSeed benutzen, wenn man Wert auf verschiedene “Zufallszahlen”-Reihen legt.

Gruß, H.

edit: Okay, Gregor war schneller.

Helmuth:
Da das nur Pseudozufallszahlen erzeugt, sollte man RandomSeed benutzen, wenn man Wert auf verschiedene “Zufallszahlen”-Reihen legt.

RandomSeed benutzt man eher, wenn man immer wieder die gleiche Folge von Zufallszahlen bekommen möchte. Zumindest kenne ich das so und es würde mich wundern, wenn das bei Arduinos anders ist.

Gruß

Gregor

Ist korrekt, aber unvollständig. :wink:

Hier ein paar Hintergründe.

Ja, gleicher RandomSeed führt immer zur gleichen Zahlenfolge.

Aber: Wenn der Wert nicht manuell gesetzt wird, arbeitet Random bei Programmstart immer mit dem gleichen Seed = exakt gleiche Ergebnisse nach Programmstart.

Übliche Arduino Lösungen: Entweder RandomSeed mit dem Input eines offenen Eingangs füttern, oder ms / µs bis zum ersten Tastendruck als Seed nehmen.

Beste Grüße, H.

edit: Das ist mir erstmalig aufgefallen, als ich eine LED Animation mit 20-30 "Zufallsparametern" gesteuert habe (ohne RandomSeed) und überrascht feststellte, dass die resultierende Animation jedesmal exakt gleich aussah. Nach dem Einsatz o.g. Lösung sah ich dann wunschgemäß jedesmal eine "neue" Animation.
Bzw. - um präzise zu sein - eine von 65536 möglichen beim einmaligen Ändern von RandomSeed.

Helmuth:
Bzw. - um präzise zu sein - eine von 65536 möglichen beim einmaligen Ändern von RandomSeed.

Na ja, random verwendet long int, also eine von 2^32 Möglichkeiten.

Helmuth:
Ist korrekt, aber unvollständig. :wink:
..l
Übliche Arduino Lösungen: Entweder RandomSeed mit dem Input eines offenen Eingangs füttern, oder ms / µs bis zum ersten Tastendruck als Seed nehmen.

Uh, ja, ich programmiere ansonsten halt eher Sachen wie einen RPi oder einen 08/15-PC. Da bin ich das mit randomSeed auf andere Weise gewohnt. Danke für die Richtigstellung und die Lösung. Momentan benötige ich das zwar nicht, aber solche Sachen lege ich gerne auf den Stapel, wo die ganzen Tipps+Tricks drin sind :slight_smile:

Gruß

Gregor

ich habe dir mal ein Grundgerüst für die Schalterabfrage, Tasterabfrage und das Blinken geschrieben, die Zufallssachen mußt du noch in die Funktionen einbauen. evtl. kannst du etwas damit anfangen.

//gemeinsamer Anschluß des Drehschalters und Taster an GND
#define pos1Pin 2
#define pos2Pin 9
#define pos3Pin 4
#define pos4Pin 5
#define tasterPin 3
#define ledRotPin 7
#define ledGruenPin 6
#define debounce_delay 15 //Entprellzeit für den Taster
bool taster_state;
bool taster_state_alt=1;

void pos1 ()
{
  //Hier die Funktion für Schalter Position 1
}
void pos2 ()
{
  //Hier die Funktion für Schalter Position 2
}
void pos3 ()
{
  //Hier die Funktion für Schalter Position 3
}
void pos4 ()
{
  //Hier die Funktion für Schalter Position 4
}


void setup() {
 Serial.begin(115200);
 Serial.println("Setup");
 pinMode(pos1Pin,INPUT_PULLUP);
 pinMode(pos2Pin,INPUT_PULLUP);
 pinMode(pos3Pin,INPUT_PULLUP);
 pinMode(pos4Pin,INPUT_PULLUP);
 pinMode(tasterPin,INPUT_PULLUP);
 pinMode(ledRotPin,OUTPUT);
 pinMode(ledGruenPin,OUTPUT);
} //Ende Setup

void loop() {
 static uint32_t debounce_time;
 if (millis()-debounce_time>debounce_delay)taster_state = digitalRead(tasterPin); //einlesen des Tasters
    Serial.println(taster_state_alt);
 if (taster_state != taster_state_alt) // bei Pegelwechsel 
    {
     if(taster_state)//wenn Taster losgelassen
        {
         if (!digitalRead (pos1Pin)) pos1();
         if (!digitalRead (pos2Pin)) pos2();
         if (!digitalRead (pos3Pin)) pos3();
         if (!digitalRead (pos4Pin)) pos4();
        }
     debounce_time=millis();
     taster_state_alt = taster_state; // state aktualisieren
     }
if(!taster_state)//wenn Taster gedrückt
  {//wechselblinken mit 500 ms
   digitalWrite(ledRotPin,(millis()%(500+500))<500);
   digitalWrite(ledGruenPin,(millis()%(500+500))>500);
   }
    else {digitalWrite(ledRotPin,0);digitalWrite(ledGruenPin,0);}
       
}//Ende Loop

Na ja, random verwendet long int, also eine von 2^32 Möglichkeiten.

Oh, danke, das ist laut Arduino Reference bei RandomSeed tatsächlich so.

Ich hatte mich blind auf Antwort #4 von hier verlassen. Mein Fehler.

Gruß, H.

Danke an alle für die guten Tipps, werd mich heute Abend dran setzen und es probieren.