Multitasking the Arduino Help out an amature to help other a

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Hatchers
 
Posts: 73
Joined: Wed Apr 12, 2017 5:58 pm

Multitasking the Arduino Help out an amature to help other a

Post by Hatchers »

Hello All

This post is a follow on from another one.
I feel like I'm the minority with in the Adafruit community where I am a complete amateur, nothing makes sense and I can't understand anything!

Please let me know I'm not alone and join this thread in the hope that we can all learn together!

I have the sudden urge to build a SONIC SCREWDRIVER
Looking for Lights, sounds and different effect at the same time wanting some control about what effects play when I push the button. All the examples are aimed towards the random display when you push a button

At this point I'm not going to go into the sound part for now!

I have invested in a Feather 34U processor and some NeoPixel sticks
My aim is to have;

push button 1 = effect 1 happens
push button 2 = effect 2 happens

easy right?
No, not if you don't know how to do it!

Ive gone through all the examples and tutorials and have made some amazing progress but have hit a brick wall.

The below script is as far as I have got and I hope that it is of some use to someone like my self out there.
Please be aware that I am a complete armature, Ive had little guidance and I'm sure that its not the best way to go around things but its a start.
The important part is towards the bottom.

The brick wall elements are
1. The script is written for 2 rings and a stick, I only have 1 stick, but when I take out anything relating to the rings it stops working
2. I am unable to integrate any other patterns in. Say for example a sparkle pattern or a ball bounce, all these are freely available how ever I am failing to turn them in to a class or a case and would like some guidance on this.

My original shout for help on the Multitasking got so many views I'm sure that there is a lot of people out there like my self that need this guidance when it comes to taming the code.

It is also my aim to once the project is complete write a tutorial and pass it to Adafruit (if they want it) to assist with other Sonic Screwdriver builds.








Code: Select all

//This is a butchered script from the Adafruit multitasking tutorial

//My set up is currently 1 NeoPixel stick with 8 LEDs#

//It is currently working as Pull pin 1 high pattern happens
//                           Pull pin 2 high another pattern happens and so on

//I have no rings, but when ever I comment out anything to do with the rings it gets very upset.

//I hope it can benefit someone when it comes to breaking down how to multitask the Arduino

//Things I am struggling with/ what this script wont help you with
//1. why cant I take out the ring function
//2. How can I integrate another pattern in here, I have managed to do a solid color but when it comes to say a twinkle or cylon or ball bounce. Any of those examples which are freely available how can you integrate them in to a scrip?




#include <Adafruit_NeoPixel.h>

// Pattern types supported:
enum  pattern { NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE, FILLRED, FILLGREEN, FILLBLUE};  //if you want to add another pattern you need to include it here
// Patern 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 RAINBOW_CYCLE:
                    RainbowCycleUpdate();
                    break;
                case THEATER_CHASE:
                    TheaterChaseUpdate();
                    break;
                case COLOR_WIPE:
                    ColorWipeUpdate();
                    break;
                case SCANNER:
                    ScannerUpdate();
                    break;
                case FADE:
                    FadeUpdate();
                    break;
                case FILLRED:              
                     FillRedUpdate();
                    break;
                case FILLBLUE:
                     FillBlueUpdate();
                     break;
                case FILLGREEN:                         //if you want to add a new pattern you need to include it here
                      FillGreenUpdate();          
                      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;
        }
    }
    /////


    //The mechanics of the patterns are here///

       
    // Initialize for a RainbowCycle
    void RainbowCycle(uint8_t interval, direction dir = FORWARD)
    {
        ActivePattern = RAINBOW_CYCLE;
        Interval = interval;
        TotalSteps = 255;
        Index = 0;
        Direction = dir;
    }
    
    // Update the Rainbow Cycle Pattern
    void RainbowCycleUpdate()
    {
        for(int i=0; i< numPixels(); i++)
        {
            setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
        }
        show();
        Increment();
    }

    // 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();
    }

    // Initialize for a ColorWipe
    void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
    {
        ActivePattern = COLOR_WIPE;
        Interval = interval;
        TotalSteps = numPixels();
        Color1 = color;
        Index = 0;
        Direction = dir;
    }
    
    // Update the Color Wipe Pattern
    void ColorWipeUpdate()
    {
        setPixelColor(Index, Color1);
        show();
        Increment();
    }
    
    // Initialize for a FILLRED
    void FillRed(uint32_t color, uint8_t interval, direction dir = FORWARD)
    {
        ActivePattern = FILLRED;
        Interval = interval;
        TotalSteps = numPixels();
        Color1 = Color1;
        Index = 0;
        Direction = dir;
    }
    
    // Update the FILLRED Pattern
    void FillRedUpdate()
    {
        setPixelColor(Index, 255,0,0);
        show();
        Increment();
   }
                // Initialize for a FILLBLUE
    void FillBlue(uint32_t color, uint8_t interval, direction dir = FORWARD)
    {
        ActivePattern = FILLBLUE;
        Interval = interval;
        TotalSteps = numPixels();
        Color1 = Color1;
        Index = 0;
        Direction = dir;
    }
    
    // Update the FILLBLUE Pattern
    void FillBlueUpdate()
    {
        setPixelColor(Index, 0,0,255);
        show();
        Increment();
    }
                
                // Initialize for a FILLGREEN
    void FillGreen(uint32_t color, uint8_t interval, direction dir = FORWARD)
    {
        ActivePattern = FILLGREEN;
        //Interval = interval;
       // TotalSteps = numPixels();
        Color1 = Color1;
       // Index = 0;
       // Direction = dir;
    }
    
    // Update the FILLGREEN Pattern
    void FillGreenUpdate()
    {
        setPixelColor(Index, 0,255,0);
        show();
        Increment();
    }
    // Initialize for a SCANNER
    void Scanner(uint32_t color1, uint8_t interval)
    {
        ActivePattern = SCANNER;
        Interval = interval;
        TotalSteps = (numPixels() - 1) * 2;
        Color1 = color1;
        Index = 0;
    }

    // Update the Scanner Pattern
    void ScannerUpdate()
    { 
        for (int i = 0; i < numPixels(); i++)
        {
            if (i == Index)  // Scan Pixel to the right
            {
                 setPixelColor(i, Color1);
            }
            else if (i == TotalSteps - Index) // Scan Pixel to the left
            {
                 setPixelColor(i, Color1);
            }
            else // Fading tail
            {
                 setPixelColor(i, DimColor(getPixelColor(i)));
            }
        }
        show();
        Increment();
    }
    
    // Initialize for a Fade
    void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD)
    {
        ActivePattern = FADE;
        Interval = interval;
        TotalSteps = steps;
        Color1 = color1;
        Color2 = color2;
        Index = 0;
        Direction = dir;
    }
    
    // Update the Fade Pattern
    void FadeUpdate()
    {
        // Calculate linear interpolation between Color1 and Color2
        // Optimise order of operations to minimize truncation error
        uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
        uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
        uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;
        
        ColorSet(Color(red, green, blue));
        show();
        Increment();
    }
   
    // Calculate 50% dimmed version of a color (used by ScannerUpdate)
    uint32_t DimColor(uint32_t color)
    {
        // Shift R, G and B components one bit to the right
        uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
        return dimColor;
    }

    // Set all pixels to a color (synchronously)
    void ColorSet(uint32_t color)
    {
        for (int i = 0; i < numPixels(); i++)
        {
            setPixelColor(i, color);
        }
        show();
    }

   // Returns the Red component of a 32-bit color
    uint8_t Red(uint32_t color)
    {
        return (color >> 16) & 0xFF;
    }

    // Returns the Green component of a 32-bit color
    uint8_t Green(uint32_t color)
    {
        return (color >> 8) & 0xFF;
    }

    // Returns the Blue component of a 32-bit color
    uint8_t Blue(uint32_t color)
    {
        return color & 0xFF;
    }
    
    // Input a value 0 to 255 to get a color value.
    // The colours are a transition r - g - b - back to r.
    uint32_t Wheel(byte WheelPos)
    {
        WheelPos = 255 - WheelPos;
        if(WheelPos < 85)
        {
            return Color(255 - WheelPos * 3, 0, WheelPos * 3);
        }
        else if(WheelPos < 170)
        {
            WheelPos -= 85;
            return Color(0, WheelPos * 3, 255 - WheelPos * 3);
        }
        else
        {
            WheelPos -= 170;
            return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
        }
    }
};

void Ring1Complete();
void Ring2Complete();
void StickComplete();

// Define some NeoPatterns for the two rings and the stick
//  as well as some completion routines
NeoPatterns Ring1(24, A1, NEO_GRB + NEO_KHZ800, &Ring1Complete);
NeoPatterns Ring2(16, A2, NEO_GRB + NEO_KHZ800, &Ring2Complete);
NeoPatterns Stick(8, A3, NEO_GRB + NEO_KHZ800, &StickComplete);     //set the number of pixels on your stick here currently 8, followed by the output pin of your processor currently A3
struct Point {
  float x;
  float y;
};


float phase = 0.0;
float phaseIncrement = 0.03;  // Controls the speed of the moving points. Higher == faster. 0.08 is quite stroby 0.01 is quite relaxed.
float colorStretch = 0.03;    // Higher numbers will produce tighter color bands. I like 0.11 .
// Initialize everything and prepare to start
void setup()
{
  Serial.begin(115200);

   pinMode(2, INPUT_PULLUP);    // the pins for your pull low are set here
   pinMode(3, INPUT_PULLUP);
   pinMode(5, INPUT_PULLUP);
   pinMode(6, INPUT_PULLUP);
   pinMode(9, INPUT_PULLUP);
   pinMode(10, INPUT_PULLUP);
   pinMode(11, INPUT_PULLUP);
   pinMode(12, INPUT_PULLUP);
    
    // Initialize all the pixelStrips
    Ring1.begin();
    Ring2.begin();
    Stick.begin();
    
    // Kick off a pattern
    Ring1.TheaterChase(Ring1.Color(255,255,0), Ring1.Color(0,0,50), 100);   //erm.... this is not working but that works in my favour
    Ring2.RainbowCycle(3);
    Ring2.Color1 = Ring1.Color1;
    Stick.Scanner(Ring1.Color(255,0,0), 55);
}

//
// Main loop
void loop()
{
    // 2 3 5 6 9 10 11 12 output pins --- these are my designated output pins
  // Choose a pattern and some colors ---- type these in below and the pattern happens //these were just notes for me so I didn't have to scroll too far up to find out what was what
       // Stick.ActivePattern = THEATER_CHASE;
       //Stick.ActivePattern = Stick.Color(255, 255, 255);
       //Stick.Color2 = Stick.Color(0, 0, 255);
       //Stick.ActivePattern =  RAINBOW_CYCLE;
       //Stick.ActivePattern = THEATER_CHASE;
       //Stick.ActivePattern = COLOR_WIPE;
       //Stick.ActivePattern = SCANNER;
       //Stick.ActivePattern = FADE;
       //Stick.ActivePattern = FILLRED;
       //Stick.ActivePattern = TWINKLE;
       //Stick.ActivePattern = FILLRED;         //I made these my self..possibly by accident
       //Stick.ActivePattern = FILLGREEN;
       //Stick.ActivePattern = FILLBLUE;
  
  // Switch patterns on a button press:                   // on pin 2 going low a fade will play
    if (digitalRead(2) == LOW) // Button #1 pressed
    {
        // Choose a pattern and some colors
       
         Stick.ActivePattern = FADE;
                 
      Stick.Update();
    }
    if (digitalRead(3) == LOW) // Button #2 pressed     // on pin 3 going low a color wipe will play and so on
    {
       // Choose a different pattern
       
       Stick.ActivePattern = COLOR_WIPE;
       
       Stick.Update();

    }

if (digitalRead(5) == LOW) // Button #2 pressed
    {
       // Choose a different pattern
       
       Stick.ActivePattern = RAINBOW_CYCLE;
       
       Stick.Update();
  }
  if (digitalRead(6) == LOW) // Button #1 pressed
    {
        // Choose a pattern and some colors
       
         Stick.ActivePattern = THEATER_CHASE;
                 
      Stick.Update();
    }
  if (digitalRead(9) == LOW) // Button #1 pressed
    {
        // Choose a pattern and some colors
       
         Stick.ActivePattern = FILLRED;
                 
      Stick.Update();
    }
  if (digitalRead(10) == LOW) // Button #1 pressed
    {
        // Choose a pattern and some colors
       
       Stick.ActivePattern = FILLGREEN;
                 
      Stick.Update();
    }
  if (digitalRead(11) == LOW) // Button #1 pressed
    {
        // Choose a pattern and some colors
       
         Stick.ActivePattern = FILLBLUE;
                 
      Stick.Update();
    }
//if (digitalRead(12) == LOW) // Button #1 pressed
  //  {
//        Choose a pattern and some colors
       
//        Stick.ActivePattern = Stick.Color(255, 0, 0);;  haven't got this bit working yet but its an example of how you would add a new pattern
                 
 //    Stick.Update();
 //   }
   }
//    else; // No button pressed?  Do nothing
//    {

//    }   
//}
//        Stick.Update();
  
//------------------------------------------------------------
//Completion Routines - get called on completion of a pattern       //these are rather esentuial and any changes here mess everything up very vauge area//
//------------------------------------------------------------

// Ring1 Completion Callback
void Ring1Complete()
{
    if (digitalRead(9) == LOW)  // Button #2 pressed
    {
        // Alternate color-wipe patterns with Ring2
        Ring2.Interval = 40;
        Ring1.Color1 = Ring1.Wheel(random(255));
        Ring1.Interval = 20000;
    }
    else  // Retrn to normal
    {
      Ring1.Reverse();
    }
}

// Ring 2 Completion Callback
void Ring2Complete()
{
    if (digitalRead(9) == LOW)  // Button #2 pressed
    {
        // Alternate color-wipe patterns with Ring1
        Ring1.Interval = 20;
        Ring2.Color1 = Ring2.Wheel(random(255));
        Ring2.Interval = 20000;
    }
    else  // Retrn to normal
    {
        Ring2.RainbowCycle(random(0,10));
    }
}

// Stick Completion Callback
void StickComplete()
{
    // Random color change for next scan
    Stick.Color1 = Stick.Wheel(random(255));
}

User avatar
Franklin97355
 
Posts: 23939
Joined: Mon Apr 21, 2008 2:33 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by Franklin97355 »

That code looks quite complicated and more than you need for a start at understanding this project. Have you looked at the example code and tried any of that?

User avatar
kcl1s
 
Posts: 1512
Joined: Tue Aug 30, 2016 12:06 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by kcl1s »

Hatchers,
I would start with the strandtest example and just modify it to work with the button presses. Setup the neopixel object for your stick, Set the pinModes for the buttons in setup and modify the loop to call the functions when a button is pushed. Something like this (not tested).

Code: Select all

void loop() {
  // Some example procedures showing how to display to the pixels:
  if (digitalRead(2) == LOW) colorWipe(strip.Color(255, 0, 0), 50); // Red
  if (digitalRead(3) == LOW) colorWipe(strip.Color(0, 255, 0), 50); // Green
  if (digitalRead(5) == LOW) colorWipe(strip.Color(0, 0, 255), 50); // Blue
//colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
  // Send a theater pixel chase in...
  if (digitalRead(6) == LOW) theaterChase(strip.Color(127, 127, 127), 50); // White
  if (digitalRead(9) == LOW) theaterChase(strip.Color(127, 0, 0), 50); // Red
  if (digitalRead(10) == LOW) theaterChase(strip.Color(0, 0, 127), 50); // Blue

  if (digitalRead(11) == LOW) rainbow(20);
  if (digitalRead(12) == LOW) rainbowCycle(20);
  // theaterChaseRainbow(50);
}
You can add different functions for others patterns and call them instead.

Keith

Hatchers
 
Posts: 73
Joined: Wed Apr 12, 2017 5:58 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by Hatchers »

Hi Keith
thanks for that
I have experimented with that before
and you have given me an Idea on how to improve the script I'm working on
however, the example sketches give no information or guidance on how to create a class or case
or how how to integrate other patterns in to the strand test,
your just thrown right into it with the multitasking example.
will have a look at it again. But I feel that I will not be achieving anything as without a class or case it will not make my final project.

One of my brick walls is how to integrate another pattern in to something like a strand test, I guess that's why Ive been fixating on the multitasking example, Plus I belive the multitasking gives the completion routines which make the whole process rather start / stop with the button pressing where the strandtest once you run a pattern its there untill completion, which is no good when you have a Cyber man to sonic!

Could someone assist me in saying for example take the FADE element out of the multitasking example (or another pattern that has a fade)
and Integrate it into the Strandtest so I can reverse engineer it.

I know this may appear simple to most and deep down I really am a clever person but I just can't see how to do it. I don't know if its my Dyslexia, or my background of being a Field service engineer who approaches everything with the concept that "It worked before, whats broken" Ive very rarely fixed something that has never worked (that's why I'm not in Production!)

I'm off now to turn my strandtest into a button pushing masterpiece with the hope of feeding in a fade at some point.
I will also document this and pass to Adafruit if they will have it, to help others like my self progress.

Hatchers
 
Posts: 73
Joined: Wed Apr 12, 2017 5:58 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by Hatchers »

Turns out I was a bit confident in my last post assuming that I could do it, but it also reminded me why I abandoned the strandtest example and focused on the multitasking
I have the following error on the attached script
colorWipe not defined
I suspect it will be the same for all the patterns in the list and if I had to guess.....would I need an update??
Any pointers would be greatly received

Code: Select all

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

#define PIN A1

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino 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)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

void setup(){
  
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
pinMode(12, INPUT_PULLUP);

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {

      // Some example procedures showing how to display to the pixels:
      if (digitalRead(2) == LOW) colorWipe(strip.Color(255, 0, 0), 50); // Red
      if (digitalRead(3) == LOW) colorWipe(strip.Color(0, 255, 0), 50); // Green
      if (digitalRead(5) == LOW) colorWipe(strip.Color(0, 0, 255), 50); // Blue
                             
    //colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
      // Send a theater pixel chase in...
      if (digitalRead(6) == LOW) theaterChase(strip.Color(127, 127, 127), 50); // White
      if (digitalRead(9) == LOW) theaterChase(strip.Color(127, 0, 0), 50); // Red
      if (digitalRead(10) == LOW) theaterChase(strip.Color(0, 0, 127), 50); // Blue

      if (digitalRead(11) == LOW) rainbow(20);
      if (digitalRead(12) == LOW) rainbowCycle(20);
      // theaterChaseRainbow(50);
    }
  // Some example procedures showing how to display to the pixels:
//  colorWipe(strip.Color(255, 0, 0), 50); // Red
 // colorWipe(strip.Color(0, 255, 0), 50); // Green
 // colorWipe(strip.Color(0, 0, 255), 50); // Blue
//colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
  // Send a theater pixel chase in...
  //theaterChase(strip.Color(127, 127, 127), 50); // White
  //theaterChase(strip.Color(127, 0, 0), 50); // Red
 // theaterChase(strip.Color(0, 0, 127), 50); // Blue

  //rainbow(20);
 // rainbowCycle(20);
  theaterChaseRainbow(50);
}

// 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 rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    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
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //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
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

User avatar
kcl1s
 
Posts: 1512
Joined: Tue Aug 30, 2016 12:06 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by kcl1s »

Hatchers,
Got to watch those extra curly brackets when you copy and paste. Take out or comment out the following 2 lines starting at line 67.

Code: Select all

  theaterChaseRainbow(50);
}

As for adding new patterns just put it inside a user function and add it to the bottom of your program. Here is an example function.

Code: Select all

void skip(int R,int G,int B,int sp) {
  for(int i=0;i<NUMPIXELS;i=i+2) {
    pixels.setPixelColor(i,pixels.Color(R,G,B));
    pixels.show();
   delay(sp);
  }
}
and call the new function from the loop when a button is pressed like this

Code: Select all

if (digitalRead(2) == LOW) skip(150,0,150,250);
The code needed for breaking out of a function loop when another button is pressed will be a little different but you will not need the extreme code you had first.
Keith

Hatchers
 
Posts: 73
Joined: Wed Apr 12, 2017 5:58 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by Hatchers »

Thanks for that
Never seen a skip before. Assuming I got it right it lights every other LED with a purple? with no motion.
Also syntax errors, nightmare, can't see them!
I'm using Arduino 1.8.2 which does not give me any line numbers or any obvious guidance when it comes to syntax errors.
Are you able to recommend anything else
I had to edit some of your text as my script didn't like pixel but wanted strip instead so big pat on the back for me there (again assuming I got it right

script attached for other followers for info

Code: Select all

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

#define PIN A1

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino 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)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

void setup(){
  
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
pinMode(12, INPUT_PULLUP);

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {

      // Some example procedures showing how to display to the pixels:
    //  if (digitalRead(2) == LOW) colorWipe(strip.Color(255, 0, 0), 50); // Red
      if (digitalRead(2) == LOW) skip(150,0,150,250);

      if (digitalRead(3) == LOW) colorWipe(strip.Color(0, 255, 0), 50); // Green
      if (digitalRead(5) == LOW) colorWipe(strip.Color(0, 0, 255), 50); // Blue
                             
    //colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
      // Send a theater pixel chase in...
      if (digitalRead(6) == LOW) theaterChase(strip.Color(127, 127, 127), 50); // White
      if (digitalRead(9) == LOW) theaterChase(strip.Color(127, 0, 0), 50); // Red
      if (digitalRead(10) == LOW) theaterChase(strip.Color(0, 0, 127), 50); // Blue

      if (digitalRead(11) == LOW) rainbow(20);
      if (digitalRead(12) == LOW) rainbowCycle(20);
      // theaterChaseRainbow(50);
    }
  // Some example procedures showing how to display to the pixels:
//  colorWipe(strip.Color(255, 0, 0), 50); // Red
 // colorWipe(strip.Color(0, 255, 0), 50); // Green
 // colorWipe(strip.Color(0, 0, 255), 50); // Blue
//colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
  // Send a theater pixel chase in...
  //theaterChase(strip.Color(127, 127, 127), 50); // White
  //theaterChase(strip.Color(127, 0, 0), 50); // Red
 // theaterChase(strip.Color(0, 0, 127), 50); // Blue

  //rainbow(20);
 // rainbowCycle(20);
//  theaterChaseRainbow(50);
//}

// 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 rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    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
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //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 skip(int R,int G,int B,int sp) {
  for(int i=0;i<strip.numPixels();i=i+2) {
    strip.setPixelColor(i,strip.Color(R,G,B));
    strip.show();
   delay(sp);
  }
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Hatchers
 
Posts: 73
Joined: Wed Apr 12, 2017 5:58 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by Hatchers »

OK back to the code above

Ive put it to a full test and it needs some tweeking and I don't know where to start
once on the more complex cycles such as the

rainbow
rainbowCycle
theaterChaseRainbow

These get stuck on the patterns and wont let me move on until it completes this cycle
how to I introduce a stop, or is it interrupt? if anther pin goes high and the user wants another pattern on command rather than waiting for it to finish its cycle.
When the pin is high I want nothing
but when it goes low I want some action!

Again, this is why I was focused on the multitasking example rather than the strand test is it had that sort of functionality.

Any advice greatly received

User avatar
kcl1s
 
Posts: 1512
Joined: Tue Aug 30, 2016 12:06 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by kcl1s »

Hatchers,
You are really not multitasking with just one neo stick. You just want to react to button presses. So the example is not right for your project. You did a good job of defining your needs in your last post.
When the pin is high I want nothing
but when it goes low I want some action!
We have the second part done in the modified strandtest code. So how can we take care of the first part. I would put a test in the innermost loop of each function to see if the button is still Low (pressed) if not return from your function back to the main loop. First let's clean up your code and define your switch pins with names that make sense to us humans. That way if you change switch pins we don't have to go through our code and find them.

Code: Select all

const int sw1 = 2;
const int sw2 = 3;
const int sw3 = 5;
const int sw4 = 6;
const int sw5 = 9;
const int sw6 = 10;
const int sw7 = 11;
const int sw8 = 12;
And the pinModes

Code: Select all

   pinMode(sw1, INPUT_PULLUP);    // the pins for your pull low are set here
   pinMode(sw2, INPUT_PULLUP);
   pinMode(sw3, INPUT_PULLUP);
   pinMode(sw4, INPUT_PULLUP);
   pinMode(sw5, INPUT_PULLUP);
   pinMode(sw6, INPUT_PULLUP);
   pinMode(sw7, INPUT_PULLUP);
   pinMode(sw8, INPUT_PULLUP);
Then add a parameter for switch to pass to the each function you call. If you use different switch pins to call the same function with different colors you will pass that different switch to the function.

Code: Select all

if (digitalRead(sw1) == LOW) colorWipe(strip.Color(255, 0, 0), 50, sw1); // Red
You will also add a corrosponding parameter to the function itself.

Code: Select all

void colorWipe(uint32_t c, uint8_t wait, uint8_t sw) {
Finally you can add a pin test to the inner most loop of the function (so it get checked a lot) to see if it is still pressed. If not return immediately to the main loop to see if another button is pressed.

Code: Select all

if (digitalRead(sw) == HIGH) return;
And here is the full modified strandtest code with the break on button release.

Code: Select all

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

#define PIN A1
const int sw1 = 2;
const int sw2 = 3;
const int sw3 = 5;
const int sw4 = 6;
const int sw5 = 9;
const int sw6 = 10;
const int sw7 = 11;
const int sw8 = 12;

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino 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)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

void setup() {
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code
   pinMode(sw1, INPUT_PULLUP);    // the pins for your pull low are set here
   pinMode(sw2, INPUT_PULLUP);
   pinMode(sw3, INPUT_PULLUP);
   pinMode(sw4, INPUT_PULLUP);
   pinMode(sw5, INPUT_PULLUP);
   pinMode(sw6, INPUT_PULLUP);
   pinMode(sw7, INPUT_PULLUP);
   pinMode(sw8, INPUT_PULLUP);

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  // Some example procedures showing how to display to the pixels:
  if (digitalRead(sw1) == LOW) colorWipe(strip.Color(255, 0, 0), 50, sw1); // Red
  if (digitalRead(sw2) == LOW) colorWipe(strip.Color(0, 255, 0), 50, sw2); // Green
  if (digitalRead(sw3) == LOW) colorWipe(strip.Color(0, 0, 255), 50, sw3); // Blue
//colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
  // Send a theater pixel chase in...
  if (digitalRead(sw4) == LOW) theaterChase(strip.Color(127, 127, 127), 50, sw4); // White
  if (digitalRead(sw5) == LOW) theaterChase(strip.Color(127, 0, 0), 50, sw5); // Red
  if (digitalRead(sw6) == LOW) theaterChase(strip.Color(0, 0, 127), 50, sw6); // Blue

  if (digitalRead(sw7) == LOW) rainbow(20, sw7);
  if (digitalRead(sw8) == LOW) rainbowCycle(20, sw8);
  // theaterChaseRainbow(50);
}

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

void rainbow(uint8_t wait, uint8_t sw) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
      if (digitalRead(sw) == HIGH) return;
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait, uint8_t sw) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
      if (digitalRead(sw) == HIGH) return;
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait, uint8_t sw) {
  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
        if (digitalRead(sw) == HIGH) return;
      }
      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
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait, uint8_t sw) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
        if (digitalRead(sw) == HIGH) return;
      }
      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
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
It is not tested but it compiles OK. Give it a try as is. Then you can try to add your other effects.

Keith
Last edited by kcl1s on Mon May 15, 2017 2:13 pm, edited 1 time in total.

Hatchers
 
Posts: 73
Joined: Wed Apr 12, 2017 5:58 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by Hatchers »

Wow thanks
Going to have to print this all out and have a go (coping tequniqe!)
excited!


Thanks again I hope not to post any syntax errors I can't work out!

Thanks again

Jo

User avatar
kcl1s
 
Posts: 1512
Joined: Tue Aug 30, 2016 12:06 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by kcl1s »

Jo,
I wanted to make it a learning moment. Can you tell I teach Arduino to teens as a hobby?

Don't forget to change the number of pixels in this line to match your stick

Code: Select all

Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
Also a few posts back you asked about line numbers in the IDE. To show line numbers go to File / preferences and check the display line number box. As for showing where syntax errors are, the compiler keeps going until something does not work right. So if you missed a curly bracket or semicolon it may be several lines until it does not work for the compiler and it throws up the error there.

Happy coding
Keith

User avatar
kcl1s
 
Posts: 1512
Joined: Tue Aug 30, 2016 12:06 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by kcl1s »

Jo,
I was just thinking you probably want the stick to go dark when no buttons are pressed. So we would need a 'for' loop at the bottom of the main loop to set all the pixels to off. I will let you give that code a try after you verify that the code I posted above works. Let me know how it goes.

Keith

Hatchers
 
Posts: 73
Joined: Wed Apr 12, 2017 5:58 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by Hatchers »

I'm so happy I belive I am spontaniously doing what is referd to as a victory dance.
I have leant some rather important lessons, slowley its starting to make some sence to me but I do know I have a long way to go.
Keith you should be proud at your self, I'm not an easy person to teach especialy in an area where I have no knowledge or experiance
well done you

Attached for info and for others is the script you kindly constructed for me.
I added the skip example you included earlier and also a ball bounce and it is all working
when low = stuff
when high = no stuff.

There are more sketches I would like to include in this and I'm stuck on one already however, I'm going to put a pin in that and find sketches I can incorporate in to this sketch

Thanks so much there is light at the end of my tunnel now :)

Code: Select all

//////////////////////////////////////////////////////////////when output pins high = nothing
/////////////////////////////////////////////////////////////when output pins low = light show
//////////////////////////////////////////////////////////// THANKS KEITH!
    #include <Adafruit_NeoPixel.h>
    #ifdef __AVR__
      #include <avr/power.h>
    #endif

    #define PIN A1
    const int sw1 = 2;
    const int sw2 = 3;
    const int sw3 = 5;
    const int sw4 = 6;
    const int sw5 = 9;
    const int sw6 = 10;
    const int sw7 = 11;
    const int sw8 = 12;

    // Parameter 1 = number of pixels in strip
    // Parameter 2 = Arduino 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)
    //   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

    // IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
    // pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
    // and minimize distance between Arduino and first pixel.  Avoid connecting
    // on a live circuit...if you must, connect GND first.

    void setup() {
      // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
      #if defined (__AVR_ATtiny85__)
        if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
      #endif
     // End of trinket special code
       pinMode(sw1, INPUT_PULLUP);    // the pins for your pull low are set here
       pinMode(sw2, INPUT_PULLUP);
       pinMode(sw3, INPUT_PULLUP);
       pinMode(sw4, INPUT_PULLUP);
       pinMode(sw5, INPUT_PULLUP);
       pinMode(sw6, INPUT_PULLUP);
       pinMode(sw7, INPUT_PULLUP);
       pinMode(sw8, INPUT_PULLUP);

      strip.begin();
      strip.show(); // Initialize all pixels to 'off'
    }

    void loop() {
      // Some example procedures showing how to display to the pixels:
      // uncommet and comment out to change the patterns
     // if (digitalRead(sw1) == LOW) colorWipe(strip.Color(255, 0, 0), 50, sw1); // Red
      //if (digitalRead(sw2) == LOW) colorWipe(strip.Color(0, 255, 0), 50, sw2); // Green
      if (digitalRead(sw1) == LOW) skip(150, 0, 150, 250, sw1);                                                                                                                                      //void skip(int R,int G,int B,int sp, uint8_t sw) {
      
      if (digitalRead (sw2) == LOW) BouncingBalls(0, 0, 255, 3, sw2);           //Bouncing balls in blue 3 = number of balls                
      if (digitalRead(sw3) == LOW) colorWipe(strip.Color(0, 0, 255), 50, sw3); // Blue
    //colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
      // Send a theater pixel chase in...
      if (digitalRead(sw4) == LOW) theaterChase(strip.Color(127, 127, 127), 50, sw4); // White
      if (digitalRead(sw5) == LOW) theaterChase(strip.Color(127, 0, 0), 50, sw5); // Red
      if (digitalRead(sw6) == LOW) theaterChase(strip.Color(0, 0, 127), 50, sw6); // Blue

      if (digitalRead(sw7) == LOW) rainbow(20, sw7);
      //if (digitalRead(sw8) == LOW) rainbowCycle(20, sw8);
      if (digitalRead(sw8) == LOW) theaterChaseRainbow(50, sw8);
    }

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

    void rainbow(uint8_t wait, uint8_t sw) {
      uint16_t i, j;

      for(j=0; j<256; j++) {
        for(i=0; i<strip.numPixels(); i++) {
          strip.setPixelColor(i, Wheel((i+j) & 255));
          if (digitalRead(sw) == HIGH) return;
        }
        strip.show();
        delay(wait);
      }
    }

    // Slightly different, this makes the rainbow equally distributed throughout
    void rainbowCycle(uint8_t wait, uint8_t sw) {
      uint16_t i, j;

      for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
        for(i=0; i< strip.numPixels(); i++) {
          strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
          if (digitalRead(sw) == HIGH) return;
        }
        strip.show();
        delay(wait);
      }
    }

    //Theatre-style crawling lights.
    void theaterChase(uint32_t c, uint8_t wait, uint8_t sw) {
      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
            if (digitalRead(sw) == HIGH) return;
          }
          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
          }
        }
      }
    }

    //Theatre-style crawling lights with rainbow effect
    void theaterChaseRainbow(uint8_t wait, uint8_t sw) {
      for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
        for (int q=0; q < 3; q++) {
          for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
            strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
            if (digitalRead(sw) == HIGH) return;
          }
          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
          }
        }
      }
    }
                //Skip example
                void skip(int R,int G,int B,int sp, uint8_t sw) {
      for(int i=0;i<strip.numPixels();i=i+2) {
        strip.setPixelColor(i,strip.Color(R,G,B));
        strip.show();
        if (digitalRead(sw) == HIGH) return;
       delay(sp);
      }
    }
              

void BouncingBalls(byte red, byte green, byte blue, int BallCount, uint8_t sw) {
  float Gravity = -9.81;
  int StartHeight = 1;
  float Height[BallCount];
  float ImpactVelocityStart = sqrt( -2 * Gravity * StartHeight );
  float ImpactVelocity[BallCount];
  float TimeSinceLastBounce[BallCount];
  int   Position[BallCount];
  long  ClockTimeSinceLastBounce[BallCount];
  float Dampening[BallCount];
  for (int i = 0 ; i < BallCount ; i++) {  
    ClockTimeSinceLastBounce[i] = millis();
    Height[i] = StartHeight;
    Position[i] = 0;
    ImpactVelocity[i] = ImpactVelocityStart;
    TimeSinceLastBounce[i] = 0;
    Dampening[i] = 0.90 - float(i)/pow(BallCount,2);
  }

  while (true) {
    for (int i = 0 ; i < BallCount ; i++) {
      TimeSinceLastBounce[i] =  millis() - ClockTimeSinceLastBounce[i];
      Height[i] = 0.5 * Gravity * pow( TimeSinceLastBounce[i]/1000 , 2.0 ) + ImpactVelocity[i] * TimeSinceLastBounce[i]/1000;
      if ( Height[i] < 0 ) {                      
        Height[i] = 0;
        ImpactVelocity[i] = Dampening[i] * ImpactVelocity[i];
        ClockTimeSinceLastBounce[i] = millis();
        if ( ImpactVelocity[i] < 0.01 ) {
          ImpactVelocity[i] = ImpactVelocityStart;
        }
      }
      Position[i] = round( Height[i] * (8 - 1) / StartHeight);
    }
    for (int i = 0 ; i < BallCount ; i++) {
      setPixel(Position[i],red,green,blue);
    }
   
    showStrip();
                if (digitalRead(sw) == HIGH) return;
    setAll(0,0,0);
  }
}
// *** REPLACE TO HERE ***

void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   FastLED.show();
#endif
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
#endif
}

void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < 8; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

    
    // Input a value 0 to 255 to get a color value.
    // The colours are a transition r - g - b - back to r.
    uint32_t Wheel(byte WheelPos) {
      WheelPos = 255 - WheelPos;
      if(WheelPos < 85) {
        return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
      }
      if(WheelPos < 170) {
        WheelPos -= 85;
        return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
      }
      WheelPos -= 170;
      return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }



Hatchers
 
Posts: 73
Joined: Wed Apr 12, 2017 5:58 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by Hatchers »

Hello

Ive also added a twinkle affect.....took me an age.
Using notepad ++ helped lots as it helped me see the {}

I've now hit a bit of a wall, all the other effects involve a class, and I'm not too sure what do do about these.
would you know what is needed to get this into my script

any advice for me to progress greatly received

Code: Select all

 /**
 * Arduino Uno - NeoPixel Fire
 * v. 1.0
 * Copyright (C) 2015 Robert Ulbricht
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <Adafruit_NeoPixel.h>

// data pin
#define PIN A1
// led count
#define CNT 8

// Parameter 1 = number of pixels in strip
// 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
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(CNT, PIN, NEO_GRB + NEO_KHZ800);

uint32_t fire_color   = strip.Color ( 80,  35,  00);
uint32_t off_color    = strip.Color (  0,  0,  0);

///
/// Fire simulator
///
class NeoFire
{
  Adafruit_NeoPixel &strip;
 public:

  NeoFire(Adafruit_NeoPixel&);
  void Draw();
  void Clear();
  void AddColor(uint8_t position, uint32_t color);
  void SubstractColor(uint8_t position, uint32_t color);
  uint32_t Blend(uint32_t color1, uint32_t color2);
  uint32_t Substract(uint32_t color1, uint32_t color2);
};

///
/// Constructor
///
NeoFire::NeoFire(Adafruit_NeoPixel& n_strip)
: strip (n_strip)
{
}

///
/// Set all colors
///
void NeoFire::Draw()
{
Clear();

for(int i=0;i<CNT;i++)
  {
  AddColor(i, fire_color);
  int r = random(80);
  uint32_t diff_color = strip.Color ( r, r/2, r/2);
  SubstractColor(i, diff_color);
  }
  
strip.show();
}

///
/// Set color of LED
///
void NeoFire::AddColor(uint8_t position, uint32_t color)
{
uint32_t blended_color = Blend(strip.getPixelColor(position), color);
strip.setPixelColor(position, blended_color);
}

///
/// Set color of LED
///
void NeoFire::SubstractColor(uint8_t position, uint32_t color)
{
uint32_t blended_color = Substract(strip.getPixelColor(position), color);
strip.setPixelColor(position, blended_color);
}

///
/// Color blending
///
uint32_t NeoFire::Blend(uint32_t color1, uint32_t color2)
{
uint8_t r1,g1,b1;
uint8_t r2,g2,b2;
uint8_t r3,g3,b3;

r1 = (uint8_t)(color1 >> 16),
g1 = (uint8_t)(color1 >>  8),
b1 = (uint8_t)(color1 >>  0);

r2 = (uint8_t)(color2 >> 16),
g2 = (uint8_t)(color2 >>  8),
b2 = (uint8_t)(color2 >>  0);

return strip.Color(constrain(r1+r2, 0, 255), constrain(g1+g2, 0, 255), constrain(b1+b2, 0, 255));
}

///
/// Color blending
///
uint32_t NeoFire::Substract(uint32_t color1, uint32_t color2)
{
uint8_t r1,g1,b1;
uint8_t r2,g2,b2;
uint8_t r3,g3,b3;
int16_t r,g,b;

r1 = (uint8_t)(color1 >> 16),
g1 = (uint8_t)(color1 >>  8),
b1 = (uint8_t)(color1 >>  0);

r2 = (uint8_t)(color2 >> 16),
g2 = (uint8_t)(color2 >>  8),
b2 = (uint8_t)(color2 >>  0);

r=(int16_t)r1-(int16_t)r2;
g=(int16_t)g1-(int16_t)g2;
b=(int16_t)b1-(int16_t)b2;
if(r<0) r=0;
if(g<0) g=0;
if(b<0) b=0;

return strip.Color(r, g, b);
}

///
/// Every LED to black
///
void NeoFire::Clear()
{
for(uint16_t i=0; i<strip.numPixels (); i++)
  strip.setPixelColor(i, off_color);
}

NeoFire fire(strip);

///
/// Setup
///
void setup()
{
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}

///
/// Main loop
///
void loop()
{
fire.Draw();
delay(random(50,150));
}

Hatchers
 
Posts: 73
Joined: Wed Apr 12, 2017 5:58 pm

Re: Multitasking the Arduino Help out an amature to help oth

Post by Hatchers »

HOLD FIRE...(pun accidential)
found another example and Ive managed to get that in!
I may be getting the hang of this!
Still not easy for me

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

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”