Sign in Join
Wiki copytemporary

AVR Embedded Tutorial - Random: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: AVR Embedded Tutorial - Random

OldNewLine
1+# Random number generator
2+
3+A random number generator is not that easy on an AVR. A random(...) function from the System unit is unfortunately not possible. This tutorial shows how to program at least one cube on an AVR.
4+
5+The range of the random number must be known from the beginning, for a classic cube this is 6.
6+
7+For communication via UART see: [[AVR Embedded Tutorial - UART|UART]].
8+
9+The following methods are suitable for simple random numbers. The prerequisite is that the random numbers are queried at irregular intervals. That is, for example. the case is also the case when a button is pressed which is queried via GPIO.
10+
11+This requirement can be seen well in the first example. If you hold down a key in the terminal program, you can easily see a regular pattern.
12+
13+If you want a **float** as a random number, it will be very complicated. I haven't found a solution (yet).
14+
15+## A single dice
16+
17+``` pascal
18+ var
19+ Random : byte; // The random number
20+
21+ procedure Timer0_Interrupt; public name 'TIMER0_OVF_ISR'; interrupt;
22+ const
23+ RandomCount = 6; // Number of dice eyes
24+ begin
25+ Inc(Random);
26+
27+ if Random >= RandomCount then
28+ begin
29+ Random := 0;
30+ end;
31+ end;
32+
33+ var
34+ s : ShortString;
35+ begin
36+ // Timer 0
37+ TCCR0A := %00; // Normal timer
38+ TCCR0B := %001; // Clock = CPU
39+ TIMSK0 := (1 shl TOIE0); // Enable Timer0 interrupt
40+
41+ // UART
42+ UARTInit; // Initialize UART
43+
44+ // Enable interrupts
45+ asm
46+ sei
47+ end;
48+
49+ // Main loop
50+ repeat
51+ UARTReadChar; // Get a keystroke
52+ Str(random + 1 : 4 , s); // Get the random number
53+ UARTSendString(s); // Output random number
54+ until 1 = 2;
55+ end.
56+```
57+
58+## Several dice
59+
60+### Bad solution
61+
62+One could get the idea and do the following with several dice:
63+
64+``` pascal
65+ Str(random + 1 : 4 , s); // Get the random number
66+ UARTSendString(s); // Output random number
67+ Str(random + 1 : 4 , s); // Depends on the first letter
68+ ...
69+```
70+
71+You get the problem that the order of the throws of the dice is predictable. Therefore this idea is unusable!
72+
73+### Ideal solution
74+
75+For this reason I have the following code, because it happens unpredictably.
76+
77+The only drawback, it is a bit more complicated, but each random number is independent of the others. In this example there are 15 dice. The timer had to be set a little slower than in the example with only one dice.
78+
79+The trick is, not all dice are incremented with every timer call. The second dice only increments with every second call, the third only with the third call, etc.
80+
81+``` pascal
82+ // Global variables.
83+ const
84+ numDice = 15;
85+ var
86+ Random : array[0..numDice - 1] of byte;
87+
88+ procedure Timer0_Interrupt; public name 'TIMER0_OVF_ISR'; interrupt;
89+ // Local variables
90+ const
91+ RandomCount = 6; // number of dice eyes
92+ var
93+ i : integer;
94+ rnd : array[0..numDice - 1] of byte;
95+
96+ begin
97+ for i := 0 to numDice - 1 do
98+ begin
99+ Inc(rnd[i]);
100+
101+ if rnd[i] > i then
102+ begin
103+ rnd[i] := 0;
104+ Inc(Random[i]);
105+
106+ if Random[i] >= RandomCount then
107+ begin
108+ Random[i] := 0;
109+ end;
110+ end;
111+ end;
112+ end;
113+
114+ var
115+ s : ShortString;
116+ i : integer;
117+
118+ begin
119+ // timer 0
120+ TCCR0A := %00; // Normal timer
121+ TCCR0B := %011; // Clock = CPU / 16
122+ TIMSK0 := (1 shl TOIE0); // Enable Timer0 interrupt
123+
124+ // UART
125+ UARTInit; // Initialize UART
126+
127+ // Enable interrupts
128+ asm
129+ sei
130+ end;
131+
132+ // Main loop
133+ repeat
134+ UARTReadChar;
135+
136+ for i := 0 to numDice - 1 do
137+ begin
138+ Str(Random[i] + 1 : 4 , s); // Each dice has its own random number
139+ UARTSendString(s);
140+ end;
141+
142+ UARTSendString(#13#10);
143+ until 1 = 2;
144+ end.
145+```
146+
147+# See also
148+
149+- [[AVR Embedded Tutorial|AVR Embedded Tutorials]] - Overview
150+
151+---
152+*From the Free Pascal wiki, page "AVR Embedded Tutorial - Random", as it stood on 2020-01-24 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
153+Category: AVR
154+Category: Arduino
155+Category: Embedded
156+Category: Tutorials

Back to history