chibiace 46 Posted August 17, 2012 Share Posted August 17, 2012 Here is a project i worked on just before christmas last year. my main use for this has been to ask it a question like a magic 8 ball and recieve an answer ranging from 1=no 6=yes Top: Bottom (strip/vero board is lovely to work with): lol no current limiting resistors. im not too sure where ive put the code, but the msp430g2231 sits in Low power mode 4 until it recieves a button press interrupt then it runs rand() and displays the number then back to sleep, ill try to keep looking for my main.c it will be around somewhere. battery still good 9 months later. bluehash and RobG 2 Quote Link to post Share on other sites
bluehash 1,581 Posted August 18, 2012 Share Posted August 18, 2012 battery still good 9 months later. ..in time for this years christmas. Quote Link to post Share on other sites
chibiace 46 Posted August 18, 2012 Author Share Posted August 18, 2012 indeed, was thinking of making this a smd kit with programming headers and a smaller coin cell battery Quote Link to post Share on other sites
dkedr 31 Posted August 19, 2012 Share Posted August 19, 2012 What did you use to generate the random number? Quote Link to post Share on other sites
chibiace 46 Posted August 19, 2012 Author Share Posted August 19, 2012 What did you use to generate the random number? something like int x = rand() % 7; still looking for that code. Quote Link to post Share on other sites
vinicius.jlantunes 50 Posted December 15, 2012 Share Posted December 15, 2012 I saw this thread orphan of code so I thought of doing the code for @chibiace's hardware. In the end I simplified it sligthly to have 7 instead of 9 LED's, thus using only P1.x. But the idea is precisely the same. The code is not yet perfect though as I am struggling to time the turning off of the LED's. I asked for help in another thread too, so as soon as this is sorted out here or there I can update the code. I will also try to upload a video of my set up. I'm a begginer so my code may have other flaws, please fell free to point them out. EDIT - issue with turning off the LED's has been resolved in the other thread. It introduces a new problem though as I am now operating all the time in LPM0. I am trying to make it exit LPM4 inside the button ISR to allow the timer to work and then go back to LMP4 once the timer ISR finishes, but am having trouble. Will update the code once that is sorted out. #include <msp430.h> #include <stdlib.h> // Constants #define TIMEWAIT 3000 // ms // Global variables int i; // For timer overflow counter int lfsr = 0xAF; // Function prototypes void turn_leds_off ( void ); int rand ( void ); int main( void ) { //---------------- // // Hardware config // //---------------- // WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer // DCO configuration DCOCTL = CALDCO_1MHZ; //Set DCO to 1 MHz BCSCTL1 = CALBC1_1MHZ; // Calibrate internal clock for 1 MHz // Timer_A configuration CCTL0 = CCIE; CCR0 = 125; // 1 ms period TACTL = TASSEL_2 + TACLR + ID_3 + MC_0; // Stopped to begin with // P1.x P1DIR = 0xF7; // All pins output except P1.3 P1IE |= BIT3; // P1.3 interrupt enable P1IES |= BIT3; // P1.3 detection edge P1IFG &= ~BIT3; // P1.3 interrupt flag cleared P1REN = 0x00; //Pull-up //----------- // // Main logic // //----------- // // Turn off all leds just in case turn_leds_off(); // Reset counter i = 0; // Low power mode 0 _BIS_SR(GIE + LPM0_bits); } void turn_leds_off ( void ) { P1OUT = 0x00; } int rand ( void ) { //unsigned int lfsr; // 16 bit version from Wikipedia unsigned bit; // LFSR polinomy x^{ 8 }+x^{ 6 }+x^{ 5 }+x^{ 4 }+1 bit = ((lfsr>>0)^(lfsr>>2)^(lfsr>>3)^(lfsr>>4)) & 1; lfsr = (lfsr>>1) | (bit<<7); // 16 bit version from Wikipedia //bit = ((lfsr>>0)^(lfsr>>2)^(lfsr>>3)^(lfsr>>5)) & 1; //lfsr = (lfsr>>1) | (bit<<15); return lfsr; } #pragma vector = PORT1_VECTOR __interrupt void button( void ) { int x; turn_leds_off(); // Turn off all leds just in case // Rolls the dice do { x = rand () % 7; } while (x == 0); // Turn on the corresponding leds // Layout of the leds P1.x as below // |0| |1| |2| // | | |7| | | // |4| |5| |6| switch (x) { case 1: P1OUT |= BIT7; break; case 2: P1OUT |= BIT2+BIT4; break; case 3: P1OUT |= BIT2+BIT7+BIT4; break; case 4: P1OUT |= BIT0+BIT2+BIT4+BIT6; break; case 5: P1OUT |= BIT0+BIT2+BIT7+BIT4+BIT6; break; case 6: P1OUT |= BIT0+BIT1+BIT2+BIT4+BIT5+BIT6; break; default: P1OUT = 0x00; } TACTL |= MC_1; // Wait a little - start timer A P1IFG &= ~BIT3; // Clears interrupt flag } #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A (void) { if (i++ >= TIMEWAIT) { TACTL = TASSEL_2 + TACLR + ID_3 + MC_0; // Stops timer i = 0; turn_leds_off(); } } Quote Link to post Share on other sites
vinicius.jlantunes 50 Posted December 15, 2012 Share Posted December 15, 2012 And here is a quick video. Sorry for the image quality, I guess I need a new camera. Quote Link to post Share on other sites
roadrunner84 466 Posted December 17, 2012 Share Posted December 17, 2012 You could also do this trick using the G2230 (a 8-pin version). Only you'd need to link LEDs (0,0) and (2,2) together, as well as (1,0) and (1,2). Same for (2,0) and (0,2), then drop LEDs (1,0) and (1,2). Now you'd only need four outputs. Then use the RESET pin as an input for the button Also, using a random number generator without a realtime clock is kind of pointless. I made a dice like this once, but I used the timespan the use pressed the button as an input (using DCO as clock source, so that's 1 MHz). I assume humans aren't that precise in pressing buttons (since you'd need microsecond precision to tamper with the dice). Also, for fair dice, make sure you don't consume more cycles at the wrap around than you'd do at the normal increment Quote Link to post Share on other sites
vinicius.jlantunes 50 Posted December 17, 2012 Share Posted December 17, 2012 Ah, that's right. I could save a few other output pins indeed! That might be useful when I do my next "step" in this project which is to have multiple dices. I decided to use the LFSR pseudo-random routine as I think it was good enough for now and I liked the fact that it relies mostly in bit operations which I think are quite efficient. I implemented an 8 bit version of it which has a 255 long period but I think I can easily convert it into a 16 bit version with a much longer period (65535). Either of them are long enough so the average human can not memorize it. But one thing annoys me - as my "seed" is fixed, if you reset the MCU then it will always give the same number to start with (I think it is 5 in above code) and then follow the usual sequence. So one could take advantage of that by memorizing at least the first few numbers and resetting the dice every know and then. I could probably randomize the seed by using a value read from the ADC or something, but then well... why not use that to use the random number itself?! So yes, I might change the method of acquiring the "random" number :-) Quote Link to post Share on other sites
spirilis 1,265 Posted December 17, 2012 Share Posted December 17, 2012 The ADC would make a good seed IMO, and it doesn't always give differing values from moment to moment (depends on local noise I guess). Sent from my C3PO via Tapatalk Quote Link to post Share on other sites
roadrunner84 466 Posted December 17, 2012 Share Posted December 17, 2012 If you plan on having multiple dice, you could use this method to have 4 driven elements (LEDs or LED pairs) per dice. You could use charlieplexing schemes to add more than the 4 dice a 20-pin MSP430G would allow you to. At 16 I/O lines (minus 1 for the button, unless using the reset as button input) you could drive 15 * 14 = 210 elements, 210/4 = 52.5. So a theoretical maximum of 52 dice, and two extra LEDs.... erm... you won't need this Quote Link to post Share on other sites
vinicius.jlantunes 50 Posted December 17, 2012 Share Posted December 17, 2012 hey that's cool! thanks for the tip roadrunner84, I will definitely look into charlieplexing. I was thinking of 5 or 6 dices but this clearly opens up the path for other ideas! :thumbup: Quote Link to post Share on other sites
abecedarian 330 Posted December 18, 2012 Share Posted December 18, 2012 Use an RTC and milliseconds as the seed? At least that's not something that people can predictably use, based on pressing a button. Quote Link to post Share on other sites
vinicius.jlantunes 50 Posted December 18, 2012 Share Posted December 18, 2012 Yeah I will get back to it next week when I am on vacation and do something to randomize the seed. I am more inclined towards using the ADC because it will be an opportunity for me to learn that bit. The only obstacle is my Xbox which keeps luring me into hours of playing. Quote Link to post Share on other sites
canibalimao 2 Posted June 6, 2013 Share Posted June 6, 2013 Hi. I'm using your code with a 7 segment display and a CD4511 and I don't know what's happening but, when I'm getting my finger close to the button, the numbers scroll randomly and only stops is I put the hand away from the board or press (without release) the button... Basically I have a cool dice that scrolls the numbers like a touch sensor. That's cool, but that's not what I want Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.