A smaller rand()?

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

A smaller rand()?

Postby SolidSilver » Sun Aug 31, 2008 11:42 am

I have a little project on the ATtiny13 that needs some random numbers. I got one rand() call in and the code went from ~150 bytes to almost 800. A second call pushed it over the limit. Sure, I could move it to a tiny85, but a) I don't have any, and b) I'm curious about alternatives to the stdlib rand() code. Part of the bloat might be the avr/delay.h stuff, as well. I'm looking into cutting that down.

Meanwhile, does anyone have a smaller solution to get some random?
User avatar
SolidSilver
 
Posts: 65
Joined: Sat Mar 31, 2007 10:29 am
Location: Portland, ME

Postby mtbf0 » Sun Aug 31, 2008 1:09 pm

if you're not using all of the a/d pins, you could try just reading an unconnected one. or, if you've got a nice noisy analog signal hooked up you sample it a few times and build a random number by shifting in the low order bit(s) of whatever you get.
"i want to lead a dissipate existence, play scratchy records and enjoy my decline" - iggy pop, i need more
User avatar
mtbf0
 
Posts: 1642
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Postby westfw » Sun Aug 31, 2008 2:57 pm

How random do you need? I used the something like the following to drive some LEDs in a "flicker" brightness that was supposed to look like flames.

Code: Select all
/*
* 127 state pseudo-random numer
* Shift register with feedback at bits 0,6
* (The macro is tested, the function is not.)
*/

#define nextrandom(last)  \
    newbit = last & 0b01000000;  /* bit 6 */  \
    if (last & 1)            /* bit 0 */ \
      newbit ^=  0b01000000; \
    last = (last>>1) + newbit;

unsigned char rand(void)
{
    static unsigned char rand_seed;
    unsigned char newbit;

    nextrandom(rand_seed);
    return(rand_seed);
}

And here's a 16bit version...
Code: Select all
/*
* pseudorandom
* return the next pseudo-random number (PRN) using a standard maximum
* length xor-feedback 16-bit shift register.
* This returns the number from 1 to 65535 in a fixed but apparently
* random sequence.  No one number repeats.
* (This is the "standard" linear shift register with xor feedback PRN;
* other PRN generators could be used.)
*/
static unsigned short pseudorandom16 (void)
{
    unsigned short newbit = 0;

    if (randreg == 0) {
        randreg = 1;
    }
    if (randreg & 0x8000) newbit = 1;
    if (randreg & 0x4000) newbit ^= 1;
    if (randreg & 0x1000) newbit ^= 1;
    if (randreg & 0x0008) newbit ^= 1;
    randreg = (randreg << 1) + newbit;
    return randreg;
}

PRNGs make for pretty ugly C code; it's one of those bit-intensive things that CAN work more elegantly in assembler.
User avatar
westfw
 
Posts: 1328
Joined: Fri Apr 27, 2007 12:01 pm
Location: SF Bay area

Thanks, westfw!

Postby SolidSilver » Mon Sep 01, 2008 11:58 am

Perfect! Swapping in the 16-bit rand routine cut the object code down to 342 bytes. Interestingly enough, this project is a flickering LED. :lol: Looks like I'll have enough room to get a more realistic dither in the pattern.

Thanks for the tip!
User avatar
SolidSilver
 
Posts: 65
Joined: Sat Mar 31, 2007 10:29 am
Location: Portland, ME

From concept to Instructable

Postby SolidSilver » Fri Sep 05, 2008 7:23 am

Thanks for the suggestions, everyone. The end result is now an Instructable project.
User avatar
SolidSilver
 
Posts: 65
Joined: Sat Mar 31, 2007 10:29 am
Location: Portland, ME

Re: A smaller rand()?

Postby SolidSilver » Wed Oct 22, 2008 12:08 pm

Woo hoo! My Instructables project got linked from Hack-a-day! (no, the link is in the story, not the headliner)
User avatar
SolidSilver
 
Posts: 65
Joined: Sat Mar 31, 2007 10:29 am
Location: Portland, ME


Return to General Project help

Who is online

Users browsing this forum: No registered users and 9 guests

Stuff to buy from the Adafruit store and links to product documentation!


New Products [114]

Raspberry Pi[82]
 
FLORA[24]
 
Bunnie Studios[9]
 
FPGA[1]
 
mbed[12]
Arduino[60]
 
NETduino[14]
 
BeagleBone[23]
 
Android[6]
 
XBee[10]
More Dev Boards[30]


 
BoArduino[8]
 
SpokePOV[4]
 
TV-B-Gone[4]
 
MiniPOV[3]
 
SIM reader[3]
 
Microtouch[5]
 
Clocks & Watches[18]
 
Drawdio[4]
 
Brain Machine[1]
 
Game of Life[2]
 
MintyBoost[2]
More DIY Kits[16]


 
MaKey MaKey[3]
 
Tweet-a-Watt[5]
 
Young Engineers[39]
 
Discover Electronics[2]
 
Snap Circuits[4]
 
littleBits[3]
 
Project packs[9]


 
Breakout Boards[35]
LCDs & Displays[49]
Components & Parts[70]
Batteries & Power[54]
EL Wire/Tape/Panel[52]
LEDs[112]
 
Wireless[16]
Cables[66]
 
Lasers[6]
Sensors/Parts[147]
 
Enclosures/Cases[11]
 
Solar[11]
 
RFID / NFC[13]
Prototyping[70]
 
iDevices[13]
Tools[71]
 
Wearables[41]
 
CNC[37]
 
Robotics[29]
 
3D printing[1]
 
Materials[25]


 
Stickers[41]
 
Skill badges[55]
 
Books[26]
 
Circuit Playground[7]
 
Gift Certificates[4]