Sunday
Sep082013

Neopixel Roulette Wheel

This was a simple little coding exercise I did for fun that simulates a mini roulette wheel on an Adafruit neopixel ring.  The code isn't perfect aesthetically, but it is functional. so go ahead, wire up 1 neopixel ring and let me know what you think!  below is a video of it running followed by the source code.  Alternately,  here is a link directly to the code.

 

     /*
    Neopixel Ring Roulette wheel sketch.
    "Spins" a roulette wheel and lands on a random value.
    I am not 100% satisfied with the aesthetic, but its as close as I can get.
    I would prefer a more realistic spinning to a slow effect with the final numbers slowly dropping onto a value
    similar to the price is right money wheel.
    I tried several approaches, but I can not seem to nail it.
    A linear increment of a delay does not look right

    If anyone can improve upon it,  I would love to see what results they come up with.
    If you make it improve it, let me know at tom[at]damage[dot]cc
    It would be rad to build a full 36+2 position American style roulette wheel out of neopixels!


    Code is based on the adafruit neopixel 'strandtest' code.
    */


    #include <Adafruit_NeoPixel.h>
    long randNumber;  //variable to hold random number value
    int pos;          //used to track position of lit segment


    //──────────────────────┤         User Variables          ├────────────────────────────

    #define PIN 6     //data pin used in for neopixel
    int spins = 6;        //how many times to 'spin before starting to slow down and settle
    #define dir 1  //set to 1 for clockwise rotation, 0 for counter clockwise.

    //───────────────────────────────────────────────────────────────────────


    // Parameter 1 = number of pixels in strip, value at 16 for NeoPixel Ring.
    // Parameter 2 = pin number (most are valid)
    // Parameter 3 = pixel type flags, add together as needed:
    //   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
    //   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
    //   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
    //   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, PIN, NEO_GRB + NEO_KHZ800);


    //──────────────────────┤       SETUP Function       ├────────────────────────────

    void setup() {
      randomSeed(analogRead(1+2+3+4+5));  //initialize floating pin (analog pins 1-5) as the seed for the RNG
      strip.begin();
      clr();  //clear the display for good measure.
      strip.show(); // Initialize all pixels to 'off'
    }


    //──────────────────────┤         Main Loop          ├────────────────────────────

    void loop() {

      randNumber=random(0,16);  //fetch a random number between 1-16

      //call the wheel
               //color used for for odd segments, even segments, and for '0'
      roulette(strip.Color(48,0,0),strip.Color(0,0,48),strip.Color(0,48,0));   
    }


    //──────────────────────┤  Roulette Wheel Function   ├────────────────────────────

    void roulette(uint32_t c,uint32_t d,uint32_t e) {

        //spin the number of times (variable 'spin') at full speed
          for (int i=0; i<16*spins; i++){
               advanceOne(c,d,e, 4);
          }   
         
          //slow down and 'settle' on final number
          for (int i=0; i<(16*6)+randNumber; i++){
               advanceOne(c,d,e, (i*.25)+4);
          }

    //optional press reset button to spin.
    //while(1);    //wait indefinitely,  press reset button on Arduino to spin again.
      delay(2000);  //reset spins automatically.

    } //end 'roulette' function


    //──────────────────────┤ Advance One Position Function ├────────────────────────────

    //every time this function is called, the led is advanced 1 position on the wheel
    void advanceOne(uint32_t c,uint32_t d,uint32_t e, uint16_t wait) {


                clr();//Clear the display

                  if ((pos & 0x01) == 0) {    //check to see if position is an even number
                        strip.setPixelColor(pos, c); //turn on the pixel at position 'pos'
                   } else  //else it is odd
                     {strip.setPixelColor(pos, d);
                   }

                  if (pos == 0) { //or check to see if it is '0'
                     strip.setPixelColor(pos, e);
                   }

                strip.show();
                delay(wait);

                if (dir){    //if direction var is set to clockwise
                      pos--;  //decrement the position
                      if(pos<0)  {pos=15;}  //resets running count if < 0}
                }
                    else{
                      pos++;  //increment the position
                      if(pos>15)  {pos=0;}  //resets running count if > 15}
                }

    }//end advanceOne function


    //──────────────────────┤ Clear all Pixels Function ├────────────────────────────

    //clears the display
    void clr(){
      for(uint16_t i=0; i<strip.numPixels(); i++) {
        strip.setPixelColor(i, 0);
        strip.show();
      }
    }

PrintView Printer Friendly Version

EmailEmail Article to Friend

References (6)

References allow you to track sources for this article, as well as articles that were written in response to this article.

Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>
« Designing an Enclosure. | Main | Futaba Transmitter Mod (Fly E-flite Bind and Flys!) »