This example demonstrate, how random numbers can be generated and how the power-down-mode can be used.
Maybe it looks easy, but it wasn't. On my first attempts some numbers seems
repeated to often. Theoretical with two independend clocks a random number
can be generated. One clock was the oscillator of the microcontroller and
the other the human, which press the button.
E.g. its possible, that on a weak battery the voltage differ on displaying
a "1" or a "6" and also the input threshold. Thus I use two different timers
with different counting values for the invisible dice and to roll the visible
LEDs.
Also there are different input thresholds on the reset pin than on any other
pin. So on short pressing the button, a reset pulse can be generated but
no low level was detected on the input. On my first attempt this caused,
that exact the next value was displayed. To avoid this, now a reset causes
nothing more than to wake up. Only, if also low level was detected a new
turn starts.
Its typically, that during a hot play the power switch was forgotten and
then the battery was empty on the next day. The solution, use no power switch,
but use the power down mode. So, if the dice was not used during 25 seconds,
all LEDs are switched of and the power down mode was entered. The same happens,
if the button was pressed permanently (>25sec) accidentally.
On pressing the button, the capacitor give a short reset pulse to wake up
from power down. After this the dice begin to run. If the button was released,
the capacitor was charged until high level was detected again.
The reset pulse width was optimized for using an inductor instead a crystal.
So a crystal was not working in this schematic , since it need a longer start
up time.
On inserting the battery, the LEDs may display wrong states, since no reset
was done. Wait some seconds and press the button and furthermore the dice
works right.
Since any pressing of the button can cause a reset, so no variables can be initialized. To do so, the startup.a51 must be modified in this way. Replace this line:
IDATALEN EQU 80H ; the length of IDATA memory in bytes.
by this line:
IDATALEN EQU 00H ; the length of IDATA memory in bytes.
Additional the program must be written in this way, that any random value
of any variable cause no malfunction, e.g. switch statement with default
case and so on.
The program was written as a state machine, so it plays no role, if the main
loop was repeated or if the loop was entered again by an external reset.
Since all 128 bytes RAM remain unchanged during reset and one of these contain
the current state, which determine the action, which was needed to enter
the next state.
This was an importand point to have fun. So the visible LEDs rolls slow enough
to give the impression, that it was possible to determine the point, at which
the dice was stopped. But the real dice counter runs many times faster and
stops unnoticed. Additional a roll out effect was implemented. So the visible
dice stops always some turns after the button was released.
To avoid manipulation, the value was displayed for minimal one second, also
if the button was pressed immediately again.