independent mode/color selecttion

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
JamesBryan
 
Posts: 134
Joined: Mon Jun 29, 2015 2:39 pm

independent mode/color selecttion

Post by JamesBryan »

I am trying to find out how to add a colour cycle button that will make the colour cycle while having a second button that will cycle through the animations so that i can go from a standard active mode to a "power up" colour change then back to normal when i push the colour cycle button again. i have found a few tutorials on how to cycle colour and how to cycle mode, but i havent found out how to make the animation look at the selected colour rather than at the function loop, meaning im trying to figure out how to make it go "theater scroll (colour)" instead of "theater scroll (0,0,255)" but i havent found an example of how to code that yet. i know i can write the colour cycle as a mode cycle if i didnt have to change animations and i could write the animation cycle to go through different colours but it would take me too many button presses to cycle through "regular ignition/regular shutdown/power up ignition/power up shutdown" how do i code a colour select function that the animation function can read so i can change colours during the animation without interrupting the animation?

User avatar
JamesBryan
 
Posts: 134
Joined: Mon Jun 29, 2015 2:39 pm

Re: independent mode/color selecttion

Post by JamesBryan »

i realize i might not have been clear enough in my post. i will post my code below, i know how to add in the second button, and am pretty sure the colour cycle can be written as a mode cycle but its geting the animation cycle to read the colour cycle that i cant figure out.

Code: Select all

    #include <Adafruit_DotStar.h> //Comment out if using NeoPixels



    // This is a demonstration on how to use an input device to trigger changes on your neo pixels.
    // You should wire a momentary push button to connect from ground to a digital IO pin.  When you
    // press the button it will change to a new pixel animation.  Note that you need to press the
    // button once to start the first animation!

    //#include <Adafruit_NeoPixel.h> //commnt out if using DotStar

    #ifdef __AVR__
    #include <avr/power.h>
    #endif


    #define BUTTON_PIN   5    // Digital IO pin connected to the button.  This will be
    // driven with a pull-up resistor so the switch should
    // pull the pin to ground momentarily.  On a high -> low
    // transition the button press logic will execute.

    #define PIXEL_PIN    0    // Digital IO pin connected to the NeoPixels.

    #define PIXEL_COUNT 60
    #define NUMPIXELS 60
    // set both of the above to the number of pixels in your strip
    // Parameter 1 = number of pixels in strip,  neopixel stick has 8
    // Parameter 2 = pin number (most are valid)
    // Parameter 3 = pixel type flags, add together as needed:
    //   NEO_RGB     Pixels are wired for RGB bitstream
    //   NEO_GRB     Pixels are wired for GRB bitstream, correct for neopixel stick
    //   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
    //   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
    //Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
    // Here's how to control the LEDs from any two pins:
    #define DATAPIN    4
    #define CLOCKPIN   3
    Adafruit_DotStar strip = Adafruit_DotStar(
                               NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_BRG);

    bool oldState = HIGH;
    int showType = 0;

    void setup() {
    #if defined (__AVR_ATtiny85__)
      if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
    #endif
      pinMode(BUTTON_PIN, INPUT_PULLUP);
      strip.begin();
      strip.show(); // Initialize all pixels to 'off'
    }
    int mode = 0;  // Start in the "Off" mode
    void loop() {

      // check for a button press
      if (digitalRead(5) == LOW)  // button pressed
      {
        mode++;  // advance to the next mode
        if (mode == 3)
        {
          mode = 0; // go back to Off
        }
      }
    }

      switch (mode) // execute code for one of the 3 modes:

      {
          {
          case 0: colorWipe(strip.Color(0, 0, 0), 10);
            break; // mode == OFF
            // add code for the "Off" mode here
            break;
          }
          {
          case 1: colorWipe(strip.Color(0, 0, 255), 5);
            // add code for the "Ignition" mode here
            break;
          }
          {
          case 2: theaterChase(0xff, 0, 0, 50); // mode == Spinning
            // add code for the "Spinning" mode here
            break;
          }
      }
    }



      // Fill the dots one after the other with a color
      void colorWipe(uint32_t c, uint8_t wait) {
        for (uint16_t i = 0; i < strip.numPixels(); i++) {
          strip.setPixelColor(i, c);
          strip.show();
          delay(wait);
        }
        void theaterChase(byte red, byte green, byte blue, int SpeedDelay) {
          for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
            for (int q = 0; q < 3; q++) {
              for (int i = 0; i < NUM_LEDS; i = i + 3) {
                setPixel(i + q, red, green, blue);  //turn every third pixel on
              }
              showStrip();

              delay(SpeedDelay);

              for (int i = 0; i < NUM_LEDS; i = i + 3) {
                setPixel(i + q, 0, 0, 0);    //turn every third pixel off

              }


Last edited by JamesBryan on Fri Feb 23, 2018 12:33 am, edited 1 time in total.

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: independent mode/color selecttion

Post by adafruit_support_mike »

What you need is a new way to organize the code.

The functions above do a complete animation cycle before execution ever goes back to a place where the microcontroller can read an input button. The structure you need is more like the BlinkWithoutDelay sketch, where the code sets the LEDs one frame at a time:

https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

With that structure, the code can check the button between any two frames of an animation.

Bill has written a great series of tutorials that show how to make code like that work:

https://learn.adafruit.com/multi-taskin ... ino-part-1
https://learn.adafruit.com/multi-taskin ... ino-part-2
https://learn.adafruit.com/multi-taskin ... ino-part-3

User avatar
JamesBryan
 
Posts: 134
Joined: Mon Jun 29, 2015 2:39 pm

Re: independent mode/color selecttion

Post by JamesBryan »

thank you, by the way i posted the wrong sketch, that one ws a rough draft and i forgot to delete it when i didnt need it any more, here is the correct sketch im using for the blade ring that im trying to add colour selection to

Code: Select all

#include <Adafruit_DotStar.h> //Comment out if using NeoPixels 



// This is a demonstration on how to use an input device to trigger changes on your neo pixels.
// You should wire a momentary push button to connect from ground to a digital IO pin.  When you
// press the button it will change to a new pixel animation.  Note that you need to press the
// button once to start the first animation!

//#include <Adafruit_NeoPixel.h> //commnt out if using DotStar

#ifdef __AVR__
#include <avr/power.h>
#endif


#define BUTTON_PIN   5    // Digital IO pin connected to the button.  This will be
// driven with a pull-up resistor so the switch should
// pull the pin to ground momentarily.  On a high -> low
// transition the button press logic will execute.

#define PIXEL_PIN    0    // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 60
#define NUMPIXELS 60
// set both of the above to the number of pixels in your strip
// Parameter 1 = number of pixels in strip,  neopixel stick has 8
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream, correct for neopixel stick
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
//Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
// Here's how to control the LEDs from any two pins:
#define DATAPIN    4
#define CLOCKPIN   3
Adafruit_DotStar strip = Adafruit_DotStar(
                           NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_BRG);

bool oldState = HIGH;
int showType = 0;

void setup() {
#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}
int mode = 0;  // Start in the "Off" mode
void loop() {

  // check for a button press
  if (digitalRead(5) == LOW)  // button pressed
  {
    mode++;  // advance to the next mode
    if (mode == 3)
    {
      mode = 0; // go back to Off
    }
  }
}

  switch (mode) // execute code for one of the 3 modes:

  {
      {
      case 0: colorWipe(strip.Color(0, 0, 0), 10);
        break; // mode == OFF
        // add code for the "Off" mode here
        break;
      }
      {
      case 1: colorWipe(strip.Color(0, 0, 255), 5);
        // add code for the "Ignition" mode here
        break;
      }
      {
      case 2: theaterChase(0xff, 0, 0, 50); // mode == Spinning
        // add code for the "Spinning" mode here
        break;
      }
  }
}



  // Fill the dots one after the other with a color
  void colorWipe(uint32_t c, uint8_t wait) {
    for (uint16_t i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
    }
    void theaterChase(byte red, byte green, byte blue, int SpeedDelay) {
      for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
        for (int q = 0; q < 3; q++) {
          for (int i = 0; i < NUM_LEDS; i = i + 3) {
            setPixel(i + q, red, green, blue);  //turn every third pixel on
          }
          showStrip();

          delay(SpeedDelay);

          for (int i = 0; i < NUM_LEDS; i = i + 3) {
            setPixel(i + q, 0, 0, 0);    //turn every third pixel off

          }



User avatar
JamesBryan
 
Posts: 134
Joined: Mon Jun 29, 2015 2:39 pm

Re: independent mode/color selecttion

Post by JamesBryan »

after reading the tutorials i have to say im actually a bit more confused than before. i do however think that this might be something uselfu if i can figure out how to use it

Code: Select all

    // Update the pattern
    void Update()
    {
        if((millis() - lastUpdate) > Interval) // time to update
        {
            lastUpdate = millis();
            switch(ActivePattern)
            {
                case RAINBOW_CYCLE:
                    RainbowCycleUpdate();
                    break;
                case THEATER_CHASE:
                    TheaterChaseUpdate();
                    break;
                case COLOR_WIPE:
                    ColorWipeUpdate();
                    break;
                case SCANNER:
                    ScannerUpdate();
                    break;
                case FADE:
                    FadeUpdate();
                    break;
                default:
                    break;
            }
        }
    }
in what im trying to do i will be using two tactile switches. i have them designated as

pinMode(7, INPUT_PULLUP); // Set pin 7 to be in input mode
pinMode(8, INPUT_PULLUP); // Set pin 8 to be in input mode
in the sketch im building. i would prefer to call them BUTTON1 and BUTTON2 if i can figure out how to code for that, but what i want BUTON1 (pinmode 7) to do is advance the animation from "off" (color wipe (0, 0, 0,) to "ignition" (the second color wipe and theater chase which for some reason the theater wipe happens right on the heels of the color wipe which gives me a much better effect than i would get if the code functioned as expected) (is there a way to make it do one animation immediately followed by the next deliberately?) and then go back to "off" and BUTTON2 (pinmode 8) should make the colors advance from blue to red to green to yellow to orange to white and then back to blue, one color per push of the button.
im thinking that perhaps i can do each set of animations in each colour and BUTTON1 will advance the animation within the active colour group while BUTON2 will change the animation group that gets triggered by BUTTON1. my ideal outcome is that i am able to change colours while the theater chase is active but the strip going blnk and then resuming in the new colour is also perfectly fine as well. if i have to cycle the animation back to "off" to be able to change colors, it may not be ideal but it will still be ok. my problem, besides the fact i have virtually no code experience to speak of, ithe tutorials i have found are very informative, but none of them even come close to addressing the type of functions i am trying to do so i cant even find specific code examples i can look at to base trying to write the code from. this is the sketch i have built so far for the dugraded disc.

Code: Select all

//#include <Adafruit_DotStar.h> //Comment out if using NeoPixels
#include <Adafruit_NeoPixel.h> //commnt out if using DotStar

#ifdef __AVR__
#include <avr/power.h>
#endif

//This sketch is to let the TRON legacy disc cycle through a selection of colours each time the colour select button is pressed
//while simultaneously allowing it to cycle through the "ignition" "blade spin" and "extinguish" animations
//when the mode select button is pressed

#define PIXEL_PIN    0    // Digital IO pin connected to the NeoPixels.

int      head  = 0, tail = -10; // Index of first 'on' and 'off' pixels
uint32_t color = 0xFF0000;      // 'On' color (starts red)

//this sets he number of pixels in the strip
#define PIXEL_COUNT 45
#define NUMPIXELS 45


//chooses which strip is being used, comment out the one you are not using
//Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_BRG)Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);



void setup()  {

#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  pinMode(7, INPUT_PULLUP);  // Set pin 7 to be in input mode
  pinMode(8, INPUT_PULLUP);  // Set pin 8 to be in input mode
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  startAnimation();     //we use () because we are not passing any parameters
}
int mode = 0;  // Start in the "Off" mode

void loop() {
  // put your main code here, to run repeatedly:

}


void startAnimation() {
  for (int x = 0; x < NUMPIXELS * 3; x++) {
    strip.setPixelColor(head, color); // 'On' pixel at head
    strip.setPixelColor(tail, 0);     // 'Off' pixel at tail
    strip.show();                     // Refresh strip
    delay(20);                        // Pause 20 milliseconds (~50 FPS)

    if (++head >= NUMPIXELS) {        // Increment head index.  Off end of strip?
      head = 0;                       //  Yes, reset head index to start
      if ((color >>= 8) == 0)         //  Next color (R->G->B) ... past blue now?
        color = 0xFF0000;             //   Yes, reset to red
    }
    if (++tail >= NUMPIXELS) tail = 0; // Increment, reset tail index
  }
}

the sketch posted in my first post is the current sketch im using in my disc and works perfectly well, the issue is that to change colours i have to plug it in to change the vairables.

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: independent mode/color selecttion

Post by adafruit_support_mike »

The general structure you're looking for is like this:

Code: Select all

uint32_t last_update = 0;   //  when we did the last strip.show()
int interval = 10;          //  10ms between updates

int animation = 0;          //  the overall sequence of LED colors
int frame_number = 0;       //  what pattern to set

void loop () {
    uint32_t now = millis();
    if (( now - last_update ) > interval ) {
        set_pixels_for( animation, frame_number );
        strip.show();
        frame_number = next_frame_in_after( animation, frame_number );
        last_update = now;
    }
    animation = check_buttons();
}
The function set_pixels_for() uses the ID of the overall animation and the frame number to calculate the pixel colors for the strip. 'animation' is roughly equivalent to the name of the do-the-whole-thing function you'd call, and 'frame_number' is equivalent to the index variable of the outermost for() loop.

The function next_frame_in_after() lets you use patterns with different numbers of LED states, and handles the problem of looping around to the beginning or moving from one pattern to another.

The function check_buttons() checks the input between updates, and either returns the current value (if no input says to change the pattern) or the ID of a new pattern.

User avatar
JamesBryan
 
Posts: 134
Joined: Mon Jun 29, 2015 2:39 pm

Re: independent mode/color selecttion

Post by JamesBryan »

i do understand the general idea of it, its the non sequential code structure that gets me. im used to BASIC where you actually had to have things in a specific order rather than just in the right section so its the flexibility that is actually my biggest stumbling block at the moment.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: independent mode/color selecttion

Post by adafruit_support_bill »

The program flow of C/C++ is not fundamentally different than BASIC. The loop Mike posted could be written in BASIC too (if it was supported on the Arduino)

The problem here is that you want the program to behave non-sequentially, so a sequential approach to programming it is not going to work.

To make the program responsive to your button presses and change what it is doing in real-time, you need to be checking the state of those buttons regularly. If your main loop is off sequencing through some pixel pattern, you will likely miss a lot of button presses.

That is why we separate the "Update" function, and only call it between checks of the button states. The Update function itself does at most one step of the animation at a time, before returning to the loop so you can check the buttons.

User avatar
JamesBryan
 
Posts: 134
Joined: Mon Jun 29, 2015 2:39 pm

Re: independent mode/color selecttion

Post by JamesBryan »

thats the thing though, i dont know what any of it is doing, so far the only reason i have been able to get as far as i have is because someone wrote the original working code which is what i used to learn how to read what its doing and gained a basic understanding of the code. now i have people telling me "well this is the general structure..." but i havent been able to find out how to actually DO any of what i want to do. i can see how the examples i have seen are doing what they do, bunt not WHAT they are doing because every time i find a sketch that looks like it performs a function that im looking for, i dont see anything i would expect to see such as how the colors it cycles through being defined. i found a theater wipe sketch that has (color1, color2,) in the multi tasking the arduino part three tutorial but nowhere in the sketch does it show HOW color1 and color2 were defined. i find something that looks like it might be a way to have it switch colors but it turns out that it makes several different pixels have different colours at the same time during the animation. i can find sketches for anything and everything under the sun except for the one thing im trying to do and the one time i find someone mention they did what im trying to do, they dont share a single line of code so i have something to work from to learn to write what i need to get what i want done. im not even asking people to write my code for me, im hoping someone can write a sample sketch with an example of how to make the colours change during a theater wipe and how to define which the colours so that i can take that and modify it for the rest of my animations or SOMETHING so that ihave an actual working example so i can actually grasp how this works, i dont learn well by just being told, i have to be able to see what it is that i am doing so i can figure it out. i catch on to things very quickly, but right now, im basically at the start of a maze but the door into the maze is seamless looking so i cant even identify which of the four walls of the room even HAS the door much less how to find the door to even start the maze. please help me understand what im trying to do here.

User avatar
JamesBryan
 
Posts: 134
Joined: Mon Jun 29, 2015 2:39 pm

Re: independent mode/color selecttion

Post by JamesBryan »

basically, im a hardware engineer who can at least understand enough of what the code monkeys are talking about where i can follow the conversation but beyond programming a VCR, im way out of my depth

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: independent mode/color selecttion

Post by adafruit_support_bill »

The tutorial series goes through things step by step and explains all of those things. Including how the theater chase colors are set:
https://learn.adafruit.com/multi-taskin ... ialization

Stripping it down to just do the TheaterChase pattern, this code implements a simple color-change on button press.

Code: Select all

#include <Adafruit_NeoPixel.h>

// Pattern types supported:
enum  pattern { NONE, THEATER_CHASE };
// Pattern directions supported:
enum  direction { FORWARD, REVERSE };

// NeoPattern Class - derived from the Adafruit_NeoPixel class
class NeoPatterns : public Adafruit_NeoPixel
{
    public:

    // Member Variables:  
    pattern  ActivePattern;  // which pattern is running
    direction Direction;     // direction to run the pattern
    
    unsigned long Interval;   // milliseconds between updates
    unsigned long lastUpdate; // last update of position
    
    uint32_t Color1, Color2;  // What colors are in use
    uint16_t TotalSteps;  // total number of steps in the pattern
    uint16_t Index;  // current step within the pattern
    
    void (*OnComplete)();  // Callback on completion of pattern
    
    // Constructor - calls base-class constructor to initialize strip
    NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)())
    :Adafruit_NeoPixel(pixels, pin, type)
    {
        OnComplete = callback;
    }
    
    // Update the pattern
    void Update()
    {
        if((millis() - lastUpdate) > Interval) // time to update
        {
            lastUpdate = millis();
            switch(ActivePattern)
            {
                case THEATER_CHASE:
                    TheaterChaseUpdate();
                    break;
                default:
                    break;
            }
        }
    }
    
    // Increment the Index and reset at the end
    void Increment()
    {
        if (Direction == FORWARD)
        {
           Index++;
           if (Index >= TotalSteps)
            {
                Index = 0;
                if (OnComplete != NULL)
                {
                    OnComplete(); // call the comlpetion callback
                }
            }
        }
        else // Direction == REVERSE
        {
            --Index;
            if (Index <= 0)
            {
                Index = TotalSteps-1;
                if (OnComplete != NULL)
                {
                    OnComplete(); // call the comlpetion callback
                }
            }
        }
    }
    
    // Reverse pattern direction
    void Reverse()
    {
        if (Direction == FORWARD)
        {
            Direction = REVERSE;
            Index = TotalSteps-1;
        }
        else
        {
            Direction = FORWARD;
            Index = 0;
        }
    }
    // Initialize for a Theater Chase
    void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
    {
        ActivePattern = THEATER_CHASE;
        Interval = interval;
        TotalSteps = numPixels();
        Color1 = color1;
        Color2 = color2;
        Index = 0;
        Direction = dir;
   }
    
    // Update the Theater Chase Pattern
    void TheaterChaseUpdate()
    {
        for(int i=0; i< numPixels(); i++)
        {
            if ((i + Index) % 3 == 0)
            {
                setPixelColor(i, Color1);
            }
            else
            {
                setPixelColor(i, Color2);
            }
        }
        show();
        Increment();
    }
};

// define a 60 pixel strip connected to pin 6
NeoPatterns strip(60, 6, NEO_GRB + NEO_KHZ800, NULL);

// Initialize everything and prepare to start
void setup()
{
  Serial.begin(115200);

   pinMode(8, INPUT_PULLUP);
    
    // Initialize all the pixelStrips
    strip.begin();
    
    // Kick off a pattern - specifying the initial colors
    strip.TheaterChase(strip.Color(255,255,0), strip.Color(0,0,50), 100);
}

// Main loop
void loop()
{
    // Update the strip.
    strip.Update();
    
    // Switch colors on a button press:
    if (digitalRead(8) == LOW) // Button #1 pressed
    {
        strip.Color1=strip.Color(0,0,255);
        strip.Color2=strip.Color(30,30,0);
    }
    else // Back to normal color on release
    {
        strip.Color1=strip.Color(255,255,0);
        strip.Color2=strip.Color(0,0,50);
    }    
}

User avatar
JamesBryan
 
Posts: 134
Joined: Mon Jun 29, 2015 2:39 pm

Re: independent mode/color selecttion

Post by JamesBryan »

i was very lucky to have someone who wrote the sketch for me and get this up and running, turns out that working from a sketch that was made with dotstars was my FIRST problem. by looking at the code and seeing it work i was able to actually learn a great deal and can understand how it works now. part of my problem is that i am a heavily visual learner and would not thought to do even one of the corrections that it took to get the code working when it ran into bugs. the colors cycling through the array got weirded out because i would have never thought to have the program use the array divided by itself as the limiting integer variable which fixed it. i plan on building another one very soon as i have ordered a second deluxe disc so i can have a pair of them and wish to submit pictures and video of the build to the learn section. how do i go about submitting something for that? also so that other people can use the code if they will find it useful:

Code: Select all

//This is to allow a NeoPixel or DotStar strip to be cycled through a preset list of animations
//as well as to all the user to change the colours of the enimations while the animations are playing
//the start animation will send a pulse of blue, red and green down the strip to indicate the device is
//booted up and ready to go as well as allow a check for dead pixels or individualk colour elements
//TRON Legacy Identity disc Mk2 (replace with the name of the project being built)

//#include <Adafruit_DotStar.h> //Comment out if using NeoPixels
#include <Adafruit_NeoPixel.h> //commnt out if using DotStar


#ifdef _AVR_
#include <avr/power.h>
#endif


#define ANIMATION_BUTTON_PIN   5    // Digital IO pin connected to the button.  This will cycle through the animations.
#define COLOR_BUTTON_PIN   6    // Digital IO pin connected to the button.  This cycle through the colors.
#define PIXEL_PIN    4    // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 37
#define NUMPIXELS 37
// set both of the above to the number of pixels in your strip
// Parameter 1 = number of pixels in strip,  neopixel stick has 8
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream, correct for neopixel stick
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
// Here's how to control the LEDs from any two pins:
#define DATAPIN    4
//#define CLOCKPIN   3 //comment out if using neopixel as clockpin is not required
//Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_BRG); //comment out if using neopixels
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800); //comment out if using dotstar

int      head  = 0, tail = -10; // Index of first 'on' and 'off' pixels
uint32_t color = 0xFF0000;      // 'On' color (starts red)



void setup() {
#if defined (_AVR_ATtiny85_)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  pinMode(ANIMATION_BUTTON_PIN, INPUT_PULLUP);
  pinMode(COLOR_BUTTON_PIN, INPUT_PULLUP);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  startAnimation();     //we use () because we are not passing any parameters
}
int mode = 0;  // Start in the "Off" mode

int colorindex = 0; //Starts in Red
int areLEDsBlank = 0;  //We did this so that the "Off" Mode isn't constantly writing to the LED Strip

//Adjust the colors here
uint32_t COLOR_ARRAY[] = {strip.Color(127, 0, 0), strip.Color(0, 255, 0), strip.Color(0, 0, 255)};


void loop() {

  // check for a button press
  if (digitalRead(ANIMATION_BUTTON_PIN) == LOW)  // button pressed
  {
    mode++;  // advance to the next mode
    if (mode == 4)
    {
      mode = 0; // go back to Off
    }
  }

  // check for a button press
  if (digitalRead(COLOR_BUTTON_PIN) == LOW)  // button pressed
  {
    colorindex++;  // advance to the next mode
    if (colorindex == sizeof(COLOR_ARRAY)/sizeof(COLOR_ARRAY[0]))
    {
      colorindex = 0; // go back to Red
    }
  }

  switch (mode) // execute code for one of the 3 modes:
  {
    case 0:
      if (areLEDsBlank != 0)
      {
        colorWipe(strip.Color(0, 0, 0), 10);
        areLEDsBlank = 0;
      }
      break; // mode == OFF

    case 1:          // add code for the "Ignition" mode here
      areLEDsBlank = 1;
      colorWipe(COLOR_ARRAY[colorindex], 5);
      break;

    case 2:          // add code for the "Spinning" mode here
      areLEDsBlank = 1;
      theaterChase(COLOR_ARRAY[colorindex], 25);
      break;
      
    case 3:          // add code for the "Ignition" mode here
      areLEDsBlank = 1;
      colorWipe(COLOR_ARRAY[colorindex], 10);
      break;
  }
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for (uint16_t i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
    for (int q = 0; q < 3; q++) {
      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, c);  //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}


void startAnimation() {

for (int i = 0; i< 4*NUMPIXELS; i++)
{ 
  strip.setPixelColor(head, color); // 'On' pixel at head
  strip.setPixelColor(tail, 0);     // 'Off' pixel at tail
  strip.show();                     // Refresh strip
  delay(20);                        // Pause 20 milliseconds (~50 FPS)

  if (++head >= NUMPIXELS) {        // Increment head index.  Off end of strip?
    head = 0;                       //  Yes, reset head index to start
    if ((color >>= 8) == 0)         //  Next color (R->G->B) ... past blue now?
      color = 0x000000;             //   Yes, reset to red
  }
  if (++tail >= NUMPIXELS) tail = 0; // Increment, reset tail index
}
}
bear in mind this code is strictly for the blade and the "C" ring uses a separate pro trinket with a simple case step to change colours because i have the colour button wired to both.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: independent mode/color selecttion

Post by adafruit_support_bill »

Glad to hear that you found something that works for you. Thanks for posting your code.

User avatar
JamesBryan
 
Posts: 134
Joined: Mon Jun 29, 2015 2:39 pm

Re: independent mode/color selecttion

Post by JamesBryan »

as you can see from my sketch, the tutorials that everyone kept suggesting wouldnt have really helped me because while they did demonstrate a lot of the same concepts, they didnt address HOW the color array works or how to make BUTTON2 actualy cycle through a list rather thn being a momentary mode swap like in the multi tasking tutorial. i can grasp the concepts very easily, but my obstacle is i need to be shown how to handle THE situation im trying to handle, not just a general concept that semi-sorta-kinda covers what im doing. im a high function autisic and my "talent" is i have an amazing abiliy to grasp concepts and apply them, i just cant learn specifics off of generals

User avatar
JamesBryan
 
Posts: 134
Joined: Mon Jun 29, 2015 2:39 pm

Re: independent mode/color selecttion

Post by JamesBryan »

i was able to write this sketch using what i learned from seeing the blae code and using it to understand the things from the tutorials and even did something that i havent seen a tutorial on yet, but was able to figure out how by seeing how code works. o havent tested it YET and am about to dolder together the components, but what this sketch is intended to do is send three colour pulses along the string and then immediately go into a slow step COLOR_WIPE to simulate the segmented boot up sequence of the disc in the movie and then stay on and wait for me to change the colours of the disc.

Code: Select all

//This is to accompany the TRON_DISCV2 sketch.
//it is for the "C" ring and will send three pulses of color down the strip to indicate
//that the board is booted and ready and then immdeiately perform a slow stepped
//color_wipe to simulate the segmented boot up effect from the movie TRON Legacy at wich time
//pressing the colour change buton on the disc will cycle the colours of the "C" ring

//#include <Adafruit_DotStar.h> //Comment out if using NeoPixels
#include <Adafruit_NeoPixel.h> //commnt out if using DotStar


#ifdef _AVR_
#include <avr/power.h>
#endif


#define COLOR_BUTTON_PIN   5    // Digital IO pin connected to the button.  This cycle through the colors.
#define PIXEL_PIN    4    // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 37
#define NUMPIXELS 37
// set both of the above to the number of pixels in your strip
// Parameter 1 = number of pixels in strip,  neopixel stick has 8
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream, correct for neopixel stick
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
// Here's how to control the LEDs from any two pins:
#define DATAPIN    4
//#define CLOCKPIN   3 //comment out if using neopixel as clockpin is not required
//Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_BRG); //comment out if using neopixels
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800); //comment out if using dotstar

int      head  = 0, tail = -10; // Index of first 'on' and 'off' pixels
uint32_t color = 0xFF0000;      // 'On' color (starts red)



void setup() {
#if defined (_AVR_ATtiny85_)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  pinMode(COLOR_BUTTON_PIN, INPUT_PULLUP);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  startAnimation();     //we use () because we are not passing any parameters

}
int mode = 0;

int colorindex = 0; //Starts in Red
//int areLEDsBlank = 0;  //We did this so that the "Off" Mode isn't constantly writing to the LED Strip

//Adjust the colors here
uint32_t COLOR_ARRAY[] = {strip.Color(127, 0, 0), strip.Color(0, 255, 0), strip.Color(0, 0, 255)};


void loop() {
  // check for a button press
  if (digitalRead(COLOR_BUTTON_PIN) == LOW)  // button pressed
  {
    colorindex++;  // advance to the next mode
    if (colorindex == sizeof(COLOR_ARRAY) / sizeof(COLOR_ARRAY[0]))
    {
      colorindex = 0; // go back to Red
    }
    switch (mode) // execute code for one of the 3 modes:
    {
      case 0:          // add code for the "Ignition" mode here
        //   areLEDsBlank = 1;
        colorWipe(COLOR_ARRAY[colorindex], 100);
        break;
    }
  }
}
  // Fill the dots one after the other with a color
  void colorWipe(uint32_t c, uint8_t wait) {
    for (uint16_t i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
    }
  }


void startAnimation() {

  for (int i = 0; i < 4 * NUMPIXELS; i++)
  {
    strip.setPixelColor(head, color); // 'On' pixel at head
    strip.setPixelColor(tail, 0);     // 'Off' pixel at tail
    strip.show();                     // Refresh strip
    delay(20);                        // Pause 20 milliseconds (~50 FPS)

    if (++head >= NUMPIXELS) {        // Increment head index.  Off end of strip?
      head = 0;                       //  Yes, reset head index to start
      if ((color >>= 8) == 0)         //  Next color (R->G->B) ... past blue now?
        color = 0x000000;             //   Yes, reset to red
    }
    if (++tail >= NUMPIXELS) tail = 0; // Increment, reset tail index
  }
}

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”