Path: Home => AVR-EN => Applications => Random ATtiny13 => Display   Diese Seite in Deutsch: Flag DE Logo
Random colors 250*250 AVR applications

Random number generation with ATtiny13
Displaying random numbers on a RGB LED in assembler

2 To display random numbers in assembler on an RGB LED with an ATtiny13

Of course, simulation is lengthy and boring, so we need some hardware to make randoms visible. Here, we display random numbers between 0 and 255*255*255 = 16.711.680 as different colors on a RGB-LED. Switching the three LEDs of that LED is done with PWM generators, that are constructed in software in an ATtiny13(A).

2.1 Hardware

Random color display with ATtiny13 The three LEDs of the RGB LED are attached to the three port pins PB0 (red LED), PB1 (green LED) and PB2 (blue LED). The current through the LEDs is controlled by resistors, which are accomodated to the different forward voltages of the LEDs. They are designed for a current of 20 mA per LED.

As different LED types have different forward voltages I corrected the three resistors later on to 100 Ω, 47 Ω and 56 Ω. That comes nearer to 20 mA than the displayed values. You'll have to check whether your RGB LEDs are more of type 1 or more of type 2. Set your operating voltage to 4.6 V or use three AA- or AAA-batteries, the resistors and measure the currents to find that out.

For those who do not have RGB LEDs of the common-anode type, you can use common-cathodes as well. Just attach the common cathodes to ground and set the PORT register bits of PB0, PB1 and PB2 to one in the init routine of the software.

To adjust the speed of the random number display, a variable resistor with 10 kΩ is attached. The resistor of 33 kΩ reduces the input voltage of the variable resistor to a range between 0 and 1.1 V. The internal reference voltage of the ADC is set to this, if you do not change the default software properties.

To the ADC2 input pin, a noise generator can be attached. This should deliver up to 1.1 Vpp. If unused, tie ADC2 to ground (which prevents random number generation from this input pin).

The device has an additional male ISP6 plug, via this the ATtiny13 can be programmed within the system, and which can also serve as supply. Die Schaltung hat noch einen ISP6-Stecker, mit dem der ATtiny13 programmiert werden kann und aus dem auch die 5V-Versorgung bezogen werden kann.

Random display and noise generator on a breadboard That is how the device with the RGB LED, the ATtiny13 and the noise generator (see Chapter 3: noise generator) look like on a breadboard.

Two short videos, with fast speed here and with slow speed here show the action. If your browser does not display the vides, download those to your computer and open them with your operating-system's favoured video display.

2.2 Program of the ATtiny13

This here shows how the program works. Those who just want to download the source code, find the assembler source here. The code can be displayed in HTML format here.

2.2.1 Options to be selected from

To cover different application cases, the program can be configured widely. To configure it, a few options on top of the source code have to be altered. Use a simple text editor for that. With the three switches swCalcOnly, swNoiseOnly and swMixed the sources of the random numbers can be modified. Only one of those three cases should be enabled. swMixed generates 15 random numbers by calculation and then sets the seed from the external noise signal.

In the section Adjustable Const further below in the source code some hardware properties can be altered. cLedLong selects the maximum duration over which the number is displayed on the LED (in tens of milliseconds). PwmFreq selects the frequency of the PWM generator for the LED display. The lower bound is 19 Hz, the upper 146 Hz.

2.2.2 Pulse width control of color combinations

PWM flow comparison To generate the pulse-width signals for the three colors, the timer/counter TC0 works in CTC mode: after 64 clock cycles of the ATtiny13 (at a default clock rate of 1.2 MHz) TC0 clears/restarts and interrupts program execution. This is the case every 64 / 1.2 = 53.3 µs. Each of those interrupts checks of the red, green and blue value (in registers rRed, rGreen and rBlue) is reached. If that is the case, the respective color bit in the register rWork is cleared. The value in those registers determines the pulse width of these colors: the higher its value the longer remains the color LED on. After 256 steps = 256 * 53.3 µs = 13,65 ms the PWM cycle is restarted. The PWM frequency therefore is 73.24 Hz.

To ensure that this switching appears immediately after the interrupt and is independant from the further instructions to be performed, the output step is done first of all. That is why the work register rWork is changed afterwards, and its changed value comes only into effect later on, at the beginning of the next interrupt.

So, switching off the LEDs is done by comparing the color color values in the registers rRed, rGreen and rBlue with the counter rPwm that counts the PWM stages upwards.

If the counter rPwm does not overflow when it is increased, the normal comparison is done with the color values. Only if the correct value is reached the respective color bit in rWork is cleared.

PWM restart If rPwm overflows to zero, a new PWM cycle is started. The number of cycles in the 16-bit-counter in rCntH:rCntL = R25:R24 is decreased. Its original content says how often the PWM cycle repeats. It stems from the multiplication of the variable resistors ADC value, so determines the speed of the display. A counter value of 73 stands for one second, up to 65535 / 73 = 898 seconds = 14.9 minutes can be achieved.

If this counter does not reach zero, the rWork register is restarted with the register content of rStart. rStart has all three color bits set, but not the ones for which the random color is zero. These LEDs are not switched on from the early start (just because they would never reach rPwm's value throughout the whole PWM cycle).

If the 16-bit counter has reached zero, three new random values have to be generated. If those are in any case calculated (Mode 1) or in any case taken from the external noise source (Mode 2) the two routes are executed. Both cases end up in the same section: the generation of rStart. Here, all bits are set that are not zero.

Following the generation of rStart the work register rWork is set to the same value adn, after restoring SREG, the service routine ends with RETI. The content of rWork is later written to the port pins, when the next CTC interrupt occurs.

None of the different diversions of the ISR should require more than 64 clock cycles. As can be seen, this is not the case, there is enough time left.

2.2.3 Random numbers

If all PWM cycles have been absolved and rCntH:rCntL reaches zero, either the calculation algorithm is used to generates the three new randoms or those are taken from the random noise generator. In both cases the values in rRed, rGreen and rBlue are redefined. Because the decision whether the three numbers are calculated (see Chapter 1 or copied from the random noise storage is decided during assembly, this decision does not require any clock cycles.

2.2.4 AD conversion and processing

The AD converter has to measure two channels:
  1. the adjustment of the speed resistor, and
  2. incoming signals on the noise generator input.
The converter is once started in the init section. The channel multiplexer is set to ADC3 and the internal reference voltage of 1.1 V is switched on. The reference voltage assures that even small signal amplitudes generate noise input. If you use a strong oscillator , like the one described in Chapter 4, you'll either can Further AD conversion is interrupt-driven. If a measurement is complete, the flag bAdc is set. The associated ISR therefore is rather short and does not influence the PWM processing. The flag handling is outside the ISR.

Which of the two channels has been measured can be be detected by reading the MUX port register.

2.2.5 Speed adjustment

If the voltage of the variable resistor has been measured, the 10-bit result is used for speed adjustment. The higher the voltage, the shorter has the counter value to be. Therefore the AD result has to be subtracted from 0x0400.

To achieve a speed adjustment that is independent from the rest of the timing (clock frequency, CTC-divider/PWM frequency, etc.) the value is multiplied with a constant that incorporates all that. The constant cMultiplier says: multiply the value to get the 256-fold of the PWM repeat counter value. If the difference of 0x0400 - ADC is 0x0400 (ADC is at 0 Volt), the counter value reflects the selected max time, as set in the constant cLedLong.

.equ cLedLong = 100 ; Longest delay in tens of ms

The multiplication constant cMultiplier
.equ cMultiplier = (((cLedLong*clock/(cCtcCmpA+1))+512)/1024)/100

is 18, if one second is selected (1023 * 18 = 18,414) and, at 10 seconds, is 183 and at 100 seconds is 1,831. This constant includes the factor 256, so skip the LSB of the multiplication result.

The multiplication of the inverted AD value (10 bits) with this value requires several registers. The inverted AD value is written to the registers R3:R2:R1:R0 (R2 and R3 are cleared). The multiplication constant is in register pair XH:XL.

The registers ZH:ZL:YH:YL hold the result of the multiplication. The upper 8 bits in ZH have to be zero after the multiplication. If not, the result is limited to 0xFFFF (largest counter value). The lowest 8 bits in YL are used fou rounding. To avoid zero as result, a one is added.

The multiplication of 1024 (ADC = 0) with 18 yields 18,432. Divided by 256 yields 72, 72 PWM cycles with 13.65 ms each lasts 0.983 seconds. At max the time can be set to 65,535 * 0.01365 = 894 seconds = 14.9 minutes.

2.2.6 Random numbers from the noise generator

If the MUX was on the ADC2 position and if the result is neither 0 nor 0x03FF, the lowest bit of the AD result is shifted from the right to the left in the three registers rRnd3:rRnd2:rRnd1. Because the AD converter works with a prescaler of 128, requires 14 clock cycles for conversion and has to measure two channels, the measuring time per bit is 128 * 14 * 2 / 1.200.000 = 3 ms. All 24 bits of a set require 72 ms. This even allows at high display speed to collect enough random bits. Even if the collection is incomplete, the left-shifting provides enough random.

If the option swMixed is selected, an additional check is made if the counter rRndC is at zero. If that is the case, the seed values in rN1 and rN2 are overwritten by the latest 16 bits random. The counter counts down in any case where the PWM-ISR calculates three new random numbers. The counter cRndC is then re-loaded with the constant cRndCount. So the calculation rows are not too long (see Chapter 1 for period lengthes).

In both cases the AD converter is restarted with the other channel.

The sleep share of the program is around 65% with these default settings. This is caused by the many PWM interrupts. If you choose a higher PWM frequency the supply current can be up to 2 mA (which can be an issue if your operating current stems from batteries). As the RGB LED can consume up to 60 mA, the controller is the smaller contributor.

Page top Main page Calculation Noise generation Analysis sine wave

Praise, error reports, scolding and spam please via the comment page to me.

©2020 by