const char *arrA[]={"4a", "2a", "3a", "1a"};
const char *arrB[]={"4b", "2b", "3b", "1b"};
const char *arrC[]={"4c", "2c", "3c", "1c"};
long rnd;
void setup() {Serial.begin(9600); randomSeed(analogRead(0));}
void loop()
{rnd=random(sizeof(arrA)/sizeof(char*));
rnd=random(sizeof(arrB)/sizeof(char*));
rnd=random(sizeof(arrC)/sizeof(char*));
Serial.print(arrA[rnd]);
Serial.print(" - ");
Serial.print(arrB[rnd]);
Serial.print(" - ");
Serial.println(arrC[rnd]);
delay(250);
}
Ich möchte bei jedem Durchgang 4 neue zufällige Wörter ausgeben.
Das ist aber kein Zufall, bei allen 3 arrays werden jeweils die gleichen Wörter gewählt,
war ums random hier garkein random?
Hi
Da Du rnd 3x einen Wert zuweist, wird bei der Ausgabe wohl der zuletzt zugewiesene Wert Da drin sein - und somit aus allen drei Array das gleiche Element ausgegeben.
MfG
uxomm
May 22, 2020, 3:34pm
3
Nur ein klein wenig umgestellt:
const char *arrA[] = {"4a", "2a", "3a", "1a"};
const char *arrB[] = {"4b", "2b", "3b", "1b"};
const char *arrC[] = {"4c", "2c", "3c", "1c"};
long rnd;
void setup() {
Serial.begin(9600);
randomSeed(analogRead(A0));
}
void loop() {
rnd = random(sizeof(arrA) / sizeof(char*));
Serial.print(arrA[rnd]);
Serial.print(" - ");
rnd = random(sizeof(arrB) / sizeof(char*));
Serial.print(arrB[rnd]);
Serial.print(" - ");
rnd = random(sizeof(arrC) / sizeof(char*));
Serial.println(arrC[rnd]);
delay(250);
}
Ohh vielen dank, das habe ich echt übersehen, ist echt ärgerlich >:(
Noch eine frage, wie kann ich den Inhalt der 3 arrays addieren, also
den text aus allen 3 arrays soll dann in einem 4ten array stehen.
Ich möchte sowas wie zufalls Sätze erstellen.
Danke
agmue
May 23, 2020, 9:32am
5
Möglicherweise ist auch snprintf ein guter Ansatz.
const char *arrA[] = {"4a", "2a", "3a", "1a"};
const char *arrB[] = {"4b", "2b", "3b", "1b"};
const char *arrC[] = {"4c", "2c", "3c", "1c"};
void setup() {
Serial.begin(115200);
Serial.println(F("\nAnfang"));
randomSeed(analogRead(A0));
}
void loop() {
static uint16_t zaehler = 1;
uint16_t rndA = random(sizeof(arrA) / sizeof(char*));
Serial.print(arrA[rndA]);
Serial.print(" - ");
uint16_t rndB = random(sizeof(arrB) / sizeof(char*));
Serial.print(arrB[rndB]);
Serial.print(" - ");
uint16_t rndC = random(sizeof(arrC) / sizeof(char*));
Serial.println(arrC[rndC]);
const byte laenge = 100;
char buf[laenge];
snprintf ( buf, laenge, "%5u: Erster Wert %s zweiter %s dritter %s gefunden.\n", zaehler, arrA[rndA], arrB[rndB], arrC[rndC]);
Serial.println(buf);
zaehler++;
delay(250);
}
snprintf ein guter Ansatz
Da gilt die Frage "Aber wozu?" noch mehr ...
Wenn das Ganze nur eine Vor-Übung ist, sollte bei µC auch PROGMEM in Erwägung gezogen werden...
Ok vielen dank an alle, ich habe jetzt 3 varianten, wobei die letzten 2 1,5kB mehr speicher fressen.
Also würde ich die erste Version vorziehen.
const char *arrA[]={"Der Apfel ", "Die Birne ", "Die Feige "};
const char *arrB[]={"ist ", "war ", "wird "};
const char *arrC[]={"rot ", "grün", "gelb"};
byte rndA, rndB, rndC;
void setup() {Serial.begin(9600); randomSeed(analogRead(0));}
void loop()
{for(int i=0; i<10; ++i)
{rndA=random(sizeof(arrA)/sizeof(char*));
rndB=random(sizeof(arrB)/sizeof(char*));
rndC=random(sizeof(arrC)/sizeof(char*));
//Example 1 2512 bytes cplusplus.com/reference/cstring/strcat/
char str[100]; strcpy(str,arrA[rndA]); strcat(str,arrB[rndB]); strcat(str,arrC[rndC]);
Serial.print(i); Serial.print(": "); Serial.println(str);
//Example 2 3936 bytes cplusplus.com/reference/cstdio/snprintf/
//const byte laenge=100; char buf[laenge];
//snprintf(buf,laenge,"%2u: %s%s%s", i, arrA[rndA], arrB[rndB], arrC[rndC]);
//Serial.println(buf);
//Example 3 3892 bytes cplusplus.com/reference/cstdio/sprintf/
//char buf[100]; sprintf(buf,"%2u: %s%s%s", i, arrA[rndA], arrB[rndB], arrC[rndC]);
//Serial.println(buf);
}
Serial.println("----------------------"); delay(2000);
}
Da gibts aber ein Problem mit dem "random"....das ist kein Zufall, nach jedem reset kommen die gleichen werte in der gleichen Reichefolge
Ich habe ein Beispiel gesehen, wo man EEPROM dazu nutz um einen echten Zufall zu erreichen.
Geht das echt nur über den Epromspeicher?
Nutze einen offenen analogen Eingang als Zufallsquelle im Setup:
void seedRandom32(uint8_t analogPort) {
uint32_t wert = analogRead(analogPort) & 0x1;
for(uint8_t i = 0; i < 32; i++) {
wert = wert << 1;
wert |= analogRead(analogPort) & 0x1;
}
Serial.print("RandomStartWert: "); Serial.println(wert,HEX);
randomSeed(wert);
}
Gruß Tommy
Wenn da irgendwas interaktives im kompletten Sketch drin ist, ist die Zeit bis zum ersten Tastendruck ein guter randomSeed Wert. Und manchmal möchte man eine "zufällige" (mit gleichverteilten Werten) aber trotzdem reproduzierbare Serie (und sei es nur zum Mogeln) : dann hilft es , den Taster schon beim Start gedrückt zu haben
Combie hat das analogRead Verfahren noch verfeinert : Nimmt für jedes Bit des int32_t - Startwerts das niederwertigste Bit eines eigenen analogRead.
Tommy56:
Nutze einen offenen analogen Eingang als Zufallsquelle im Setup:
void seedRandom32(uint8_t analogPort) {
uint32_t wert = analogRead(analogPort) & 0x1;
for(uint8_t i = 0; i < 32; i++) {
wert = wert << 1;
wert |= analogRead(analogPort) & 0x1;
}
Serial.print("RandomStartWert: "); Serial.println(wert,HEX);
randomSeed(wert);
}
Gruß Tommy
Wie ruft man diese Funktion "seedRandom32" auf?
Im setup
seedRandom32(A0);
wenn Du A0 nicht belegt hast.
Gruß Tommy