Hallo zusammen,
ich plane eine kleine Einrichtung, die folgendes Element enthalten muss:
Einen "Zufallsgenerator", der zufällig aber mit festem Mittelwert (und
der soll einstellbar 10 min oder 1 stunde betragen) anspringt. Ich
brauche also lediglich ein digitales signal, das für kurze zeit um den
festen mittelwert zufällig auftritt.
Wie ich das Signal generiere ist eigentlich an keine Bedingungen
geknüpft, nur an folgen(schwere)de: die gesamte Elektronik muss
möglichst klein sein und sollte minimalen stromverbrauch haben, da sie
wie eine uhr über viele tage mit batterie funktionieren soll.
Was würdet ihr vorschlagen? Gibt es andere sinnvolle Ansätze als über
einen µC? Wenn einen µC nehmen - welchen (kleinen) AVR? Ich kann nicht
Assembler programmieren - wenn es ein kleiner AVR werden würde, wie
schwer wäre die umsetzung in assembler für einen laien?
Beste Grüße
Alex
achja, bevor der kommentar auftritt, dass echter zufall mit dem µC
ohnehin nicht möglich ist: Es muss kein echter sein, er muss nur echt
wirken (also bei längerer beobachtung nicht eindeutig ein muster
aufweisen).
> Einen "Zufallsgenerator", der zufällig aber mit festem Mittelwert (und> der soll einstellbar 10 min oder 1 stunde betragen) anspringt.
Dann mußt du ja nur das Doppelte des Mittelwerts als Obergrenze in einen
Zufallsgenerator einspeisen und dann die ermittelte Zeit abwarten.
> Gibt es andere sinnvolle Ansätze als über einen µC?
Eher nein. Die Zufallskomponente könntest du zwar als LFSR auch mit
diskreten Komponenten aufbauen, aber dann bekommst du damit ein Problem:
> die gesamte Elektronik muss möglichst klein sein
Diese Aufgabe schreit laut nach einem 6 oder 8 Pin uC.
> wie schwer wäre die umsetzung in assembler für einen laien?
Das ist nicht trivial, denn du mußt mit Sleep-Modes usw. herumkämpfen...
Ich würde da wenn du ganz von vorn beginnst, mit einem Zeitaufwand von
ca. 1 Monat rechnen.
> Ich kann nicht Assembler programmieren
Kannst du C?
c++ gut,
c ausreichend für bisherige µC projekte allerdings noch exkl interrupts
und timer (ja was bleibt da schon übrig =D )
Ich hab den Attiny 13 herumliegen... aber ein monat ist mir zu lang!
Du kannst ja mit dem ADC des AVRs etwas rauschendes, z.B. eine Z-Diode
vermessen. Per Portpin kannst du diese zwecks Stromverbrauch abschaltbar
machen.
Ein externer Rauschgenerator wie z.B.
http://www.ve6aqo.com/images/Leo_Rauschgenerator/Rauschgen_m..jpg
wird vom AD-Wandler des AVR abgetastet. Die so ermittelten Werte können
als Initialisierungsvektor oder als Muster zur Art der Rückkopplung für
ein LRSR
http://de.wikipedia.org/wiki/Linear_r%C3%BCckgekoppeltes_Schieberegister
dienen.
Dies sollte dir eine konstante Zufallsverteilung geben, deren Mittelwert
die Hälfte des maximal erreichbaren Wertes ergibt.
Wenn das Aufbauen des Rauschgenerators zu aufwändig oder zu
stromintensiv ist, reicht vielleicht (je nach Umgebung) auch das Samplen
eines digitalen Eingangspins. Der darf dann natürlich keine
Pull-Up/Pull-Down-Widerstände haben.
Ich denke das Generieren der Zufallszahl ist nicht das große Problem an
sich. Für viele Zwecke ist rand() gut genug.
Den Teil den man lernen muss ist: wie wartet man möglichst Stromsparend
eine gewisse Zeit lang ab.
danke für die antworten soweit!
Das ganze soll (mit knopfzelle) auf die größe einer uhr gebracht werden
- ist dein Ansatz (@MoritzS) da realisierbar?
Was ist nur durch programmiertechnik maximal auf der bereits vorandenen
hardwareebene eines avrs möglich, den ich nehmen könnte?
Bzw immernoch das problem der größe - die AtMega 16 die ich
programmieren kann sind ja ein bisschen zu groß ;)
Was ist der kleinste AVR, der sich in C programmieren lässt?
> Was ist der kleinste AVR, der sich in C programmieren lässt?
Nimm irgendwas in der Liga um den Attiny45 mit 8 Pins dann hast du
genügend Luft. Wenns dann in Serie gehen soll und du zigtausende Geräte
brauchst kannst du immer noch optimieren....
BTW: vergiss diese Pseudo-Zufallszahlen mit AD-Wandler und
Rauschgenerator, bis die wirklich zufällige Zahlen liefern hast du
schon lange das Ding mit rand() ausreichend zufällig am laufen (du
brauchst ja nur 1 neue Zufallszahl alle 10 Minuten bis 1h).
danke.
ich habe die funktion rand() lange nicht mehr benutzt - und erinnere
mich (hoffentlich richtig?) daran, dass ich eine zahl vorgebe, die dann
die obere grenze der generierten zufallszahl gilt.
Wenn ich nun als obere grenze das doppelte der zahl nehme ist mein
mittelwert die zahl selbst?
Das wäre dann vielleicht schon eine ausreichende lösung.
Alex schrieb:> danke.> ich habe die funktion rand() lange nicht mehr benutzt - und erinnere> mich (hoffentlich richtig?) daran, dass ich eine zahl vorgebe, die dann> die obere grenze der generierten zufallszahl gilt.
falsch.
rand() liefert eine Zahl zwischen 0 und RAND_MAX
Was du dann mit dieser Zahl weiter machst, obliegt ganz dir. Du kannst
sie zb durch eine Bereichsgröße modulo nehmen(ja ich weiß, ist nicht
optimal) und eine Untergrenze dazuzählen. Was auch immer du willst.
> Wenn ich nun als obere grenze das doppelte der zahl nehme ist mein> mittelwert die zahl selbst?
Yep.
ATTiny13A wäre auch mein Tipp.
Algorithmen für Zufallszahlengeneratoren dürften nicht schwer zu finden
sein. Du musst halt den passenden finden, der die Verteilung hat, die du
anstrebst bzw. wie man die Werte von rand() so umrechnet, dass diese
Verteilung herauskommt. Problematisch ist da natürlich immer noch, den
Startwert zu finden. Man könnte aber immer den neusten Wert als seed ins
EEPROM schreiben.
Tja, und du musst dich halt mit dem Sleep-Modus auseinander setzen.
Alex schrieb:> Das wäre dann vielleicht schon eine ausreichende lösung.
Für ein Casin0 wirds nicht reichen, aber für den Hausgebrauch ist rand()
eine ausreichend gute Lösung.
Wie soll denn dein digitales Signal überhaupt ausgegeben werden?
Wie viele Bits sollen (pseudo-)zufällig werden? So ganz ist mir
die Aufgabe noch nicht klar.
> Wie viele Bits sollen (pseudo-)zufällig werden?
So wie ich das verstanden habe, soll die Zeit zwischen 2 Ipulsen
zufällig sein, aber im langjährigen Mittel um die 10 Minuten (also
brauche ich eine zufallszeit von 0 bis 20 Minuten). Oder 1 Stunde, oder
irgendwas einstellbares dazwischen.
Lothar Miller schrieb:> im langjährigen Mittel um die 10 Minuten
Naja, dann kann ich aber auch einen Fall haben in dem ich 59 mal nur
eine Sekunde warte, und einmal 599 min 1 sek - das macht im Schnitt auch
10 Minuten ;-)
Alleine den Mittelwert vorgeben reicht mMn nicht, es bräuchte auch eine
Angabe wie stark die Zufallswerte denn um dieses Mittel streuen
sollen/dürfen.
Quick hack, als Diskussionsbasis. (Nicht getestet, keine Garantie,
nicht auf lebende Menschen oder Tiere anwenden oder in der Luft- und
Raumfahrt benutzen usw. usf. ;-)
Ich war vor allem mal neugierig, ob das in einen ATtiny13 überhaupt
reinpassen würde, schließlich werden ja Divisionen/Modulo-Operationen
benötigt. Keine Angst, der Gleitkommakram wird komplett vom Compiler
aufgedröselt, schreibt sich so halt nur einfacher hin. ;-)
Immerhin, ist derzeit nur zu 75 % ausgelastet, ich hatte schlimmeres
befürchtet.
Das sollte unserem Kandidaten vielleicht erstmal als Basis für
eigene Experimente genügen.
Die Ruhestromaufnahme sollte bei einigen 10 µA liegen. Weniger würde
nur noch gehen mit Controllern, deren Timer man im Schlaf mit einem
32-kHz-Quarz takten lassen kann, damit man den Haupttakt ausschalten
kann.
zu oben (spezifizierung der zufalls/mittelgeschichten):
Bei der Einstellung 10 min soll im Mittel alle 10 minuten ein high
Impuls (und so gesehen ein Bit) (der länge 1-3s) ausgegeben werden, der
einen transistor ansteuert. Das "Mittel" ist so gemeint, dass nach dem
Einschalten beispielsweise nach 7 minuten der erste Impuls, dann nach
13, dann nach 16, dann nach 4 [...] ein Impuls kommt. Obergrenze
zwischen den Impulsen sollte 20-40 minuten nicht überschreiten.
@Jörg
Herzlichen Dank für das Codebeispiel! Das hilft mir sehr weiter, denke
ich.
Ich bin eher hobby- und gelegenheitsprogrammierer deshalb meine Fragen,
die sich höchstwahrsch. schon aus dem code beantworten lassen...:
-Du nutzt den internen Oszillator des AtTiny13?
- Mit AVRStudio (AVRGCC) und einem isp adapter ist der code so auf den
tiny13 flashbar?
@Mark
Gaußverteilt wäre nicht verkehrt ;) aber so wichtig ist das nicht,
zweiseitig exponentialverteilt ginge auch etc... es geht dabei in erster
linie um eine sinnvolle verteilung, was hier bedeutet dass ich
vielleicht zu 80-90% innerhalb von 15 minuten den nächsten Impuls
bekomme...
Alex schrieb:> zu oben (spezifizierung der zufalls/mittelgeschichten):> Bei der Einstellung 10 min soll im Mittel alle 10 minuten ein high> Impuls (und so gesehen ein Bit) (der länge 1-3s) ausgegeben werden, der> einen transistor ansteuert. Das "Mittel" ist so gemeint, dass nach dem> Einschalten beispielsweise nach 7 minuten der erste Impuls, dann nach> 13, dann nach 16, dann nach 4 [...] ein Impuls kommt. Obergrenze> zwischen den Impulsen sollte 20-40 minuten nicht überschreiten.
Einige dich mit dir selber welches die kürzeste Zeit sein soll nach der
der nächste Puls kommt und welches die längste.
rand() % ( max - min ) + min
das ist die Zeit, die du als nächstes warten willst.
> vielleicht zu 80-90% innerhalb von 15 minuten den nächsten Impuls> bekomme...
was solls denn eigentlich werden?
Die genaue Beschreibung macht hier nicht so viel sinn aber es wird eine
Armbanduhr, die nicht die Zeit anzeigt sondern (einstellbar) als
Erinnerer funktioniert.
Da das ganze als Konditionierung funktionieren soll, die später nicht
von dem Signal selber sondern von der Erwartung des Signals abhängt
(damit die Uhr irgendwann weggelassen werden kann) ist die zufälligkeit
nötig.
Die Erinnerung funktioniert über eine kurze vibration.
Dafür bin ich übrigens immernoch bei der Suche nach einem
(online)Anbieter in Deutschland, der möglichst kleine Vibrationsmotoren
in scheibenform verkauft. Falls hier also einer bekannt sein sollte bin
ich für Links wie immer dankbar.
Zum Thema kleine Vibrationsmotoren, wenn du ein altes Handy hast das du
nicht mehr benötigst kannst du es ausschlachten. Dort sollte sich ein
kleiner Motor befinden
Alex schrieb:> Herzlichen Dank für das Codebeispiel! Das hilft mir sehr weiter,> denke ich.
Ja, wenn du schon mal C programmiert hast, solltest du dich in so ein
"Gerippe" schneller reinfinden können, als es von null auf selbst zu
zimmern.
> - Du nutzt den internen Oszillator des AtTiny13?
Ich nutze gar nichts. ;-) Ja, ich habe es auf den internen 9,6-
MHz-Oszillator des ATtiny13 ausgelegt, der standardmäßig aktiv ist.
> - Mit AVRStudio (AVRGCC) und einem isp adapter ist der code so auf> den tiny13 flashbar?
Weiß ich nicht, hab' kein AVR Studio. :) Ich würde allerdings davon
ausgehen, dass man das machen kann.
Der Prozessortakt von 9,6 MHz wird nur während der aktiven Phase
benutzt, danach wird er runtergeteilt durch 256 (über den clock
prescaler), das sind also einige 10 kHz. Dieser Takt wird dann
nochmals durch 1024 geteilt für den Timer, der nach 256 Schritten
überläuft. Das entspricht ziemlich genau 7 s pro Überlauf, und nach
jedem Überlauf wacht der Prozessor auf. Diese 7 s sind dann auch die
Granularität der Ereignisse.
> Gaußverteilt wäre nicht verkehrt ;)
Naja, da müsstest du wohl mehr Aufwand reinstecken, und ich fürchte,
dass dann der ATtiny13 auch nicht mehr ausreicht. rand() ist einfach
nur gleichverteilt.
Hallo,
die diskussion hier ist einige zeit her und ich laufe seit ebenfalls
einiger zeit mit meinem prototypen in der tasche herum, der nach deinem
(jörg) code so super läuft. nun habe ich allerdings noch das problem,
dass die gesamte schaltung, die in einem fach einer micro AAA zelle
platz finden muss (und bislang auch tut) ein/ausschaltbar sein muss.
da ich keine mechanischen schalter der größe und form finde, wie ich sie
brauche, dachte ich daran, die schaltung über einen taster in und aus
dem sleep mode zu holen.
nun hat sich mein grundverständnis bzgl dem obigen code zwar verbessert,
er reicht aber noch nicht aus, um das einfache folgende zu
implementieren:
einfacher tasterdruck -> µC geht in den sleep mode
erneuter tastendruck -> µC geht aus dem sleep mode und führt die
mainschleife aus.
ich bin auch nicht sicher, ob das noch auf den tiny passt bzw wie man es
coden müsste, damit das auch noch draufpasst?
ich denke die frage ist für die meisten hier lächerlich einfach, für
mich aber aufgrund der leidigen interrupt/sleepmode einarbeitung noch
nicht ganz trivial.
kann mir da jemand helfen oder ein codebeispiel geben?
Viele Grüße
Alex
Halo Alex,
wenn Du statt eines AVR einen PIC nehemn koenntes, koennte ich Dir das
schicken.
Der Zufallsgenerator sind 7 Zeilen Assemblercode, die skalierung nochmal
drei und das meiste ist die Initialisierung des Chips.
Echte Peanuts.
Gruss
Michael
hallo michael,
uuh mit PICs (genauso wie assembler) habe ich so GAR keine erfahrung! :(
dafür bin ich wohl noch nicht genug in der materie ... wie programmiere
ich die denn (hardwaremäßig)?
ich glaube dafür müsste ich mein bisheriges projekt zu sehr
umkrempeln...
herzlichen dank für das angebot!