Shop OBEX P1 Docs P2 Docs Learn Events
Magic Cauldron effect — Parallax Forums

Magic Cauldron effect

Make Magazine always has interesting things in their email newsletter. The other day, there was a link to this Magic Cauldron project:
https://community.makezine.com/share/ianmckay/magic-cauldron-6da6b1

I thought the idea was interesting, and the way he put it in a cauldron with glass beads to diffuse the glow was good, but after I saw the second video, I figured the lighting effect could be a lot better. It looks too much like someone flipped a switch to pick the selected color, instead of a magical, mystical glow. So I spent some time on it:
- Wrote my version for the Propeller instead of the Arduino
- When activated, swirling colors fade in, then fade down
- The selected color turns on and then fades out

I'm not quite happy with the transition from the swirling rainbow to the selected color, but I figure I'd share it here, someone may find a use for it. You'll need an Adafruit NeoPixel ring to see the effect.

Comments

  • JonnyMacJonnyMac Posts: 9,104
    edited 2016-09-23 06:08
    A couple notes that may be helpful.

    You don't need RealRandom to seed Heater's PRNG object -- there's enough jitter in the start-up of the cnt register that I now do it like this:
    prng.seed(-cnt, -cnt ~> 2, $EA7_BEEF, cnt <- 2, cnt)
    

    I needed a color morph effect for a WS2812 project and did it like this:
    pub morph(rgb1, rgb2, phase) | idx
    
      phase &= $FF
    
      if (phase == 0)
        return rgb1
    
      if (phase == $FF)
        return rgb2
    
      repeat idx from 0 to 2
        result.byte[idx] := rgb2.byte[idx] * phase / $FF
        result.byte[idx] += rgb1.byte[idx] * ($FF-phase) / $FF
    
    This can be useful for smooth color-to-color transitions.

  • Jon, thanks!

    I should have some time this weekend to try these out.
  • Hi Jon,

    The revised seed method for PRNG is great, thanks.

    It took a bit for me to figure out a good way to use the morph method. Here's an abbreviated version of what I've got so far:
    
    pub main | fade
    
           repeat fade from 0 to 255
               strip.fill(0,15,(morph($00_00_FF, $00_00_00, fade)))     ' fade Blue to Black
               time.pause(5)
    

    This is a really nice fade effect. I think I see how to apply this to the wheel effects, it seems there's an additional level of nesting required, but that's as far as I've got right now.

    Jeff
  • The morph method is meant to provide a transition from one color to another. In my case with the meditation ring, I had to go from red, to orange, to yellow, to green, etc... and then pink was in the mix. Anyway, it worked well.

    When you're fading a pure color up or down, you can simplify. To go from blue to black, you could also do this:
      t := cnt
      repeat fade from 255 to 0
        strip.fill(0, 15, (fade << 0))
        waitcnt(t += (5 * MS_001))
    
    If you change << 0 to << 1 you'll fade the green channel, << 2 for the red channel. My acting teacher used to say that as there are many roads that lead to Rome, there are many ways to approach a problem. Here's another road for your programming travels!

    It like to use waitcnt in these cases as it takes care of the loop overhead and ensures the fade timing is constant.
  • Jon, thanks again. I set up multiple morphs to see how the colors changed, it's really nice. You'll have to tell us a bit more about the meditation ring.

    For the fade code, there's something I'm missing. Maybe it's too late Sunday night, but...

    This works for me:
             strip.fill(0, 15, $00_00_FF)     ' Blink Blue on
    
             time.pause(4000)                 ' Hold color for a moment
              
             t := cnt
             repeat fade from 255 to 0
                strip.fill(0, 15, (fade << 0))  ' Results in Blue fading out
                waitcnt(t += (5 * MS_001))
    

    This does not:
             strip.fill(0, 15, $00_FF_00)   ' Blink Green on
    
             time.pause(4000)                ' Hold color for a moment
              
             t := cnt
             repeat fade from 255 to 0
                strip.fill(0, 15, (fade << 1))   ' Results in Blue flashing twice
                waitcnt(t += (5 * MS_001))
    
    Setting strip.fill(0, 15, (fade << 2)) results in Blue flashing three times.
  • JonnyMacJonnyMac Posts: 9,104
    edited 2016-09-26 13:20
    That's what I get for making a suggestion without testing! The color shift needs to be multipled by 8 for bits. This is running on my desk:
    pub main | ch                                              
                                                                     
      setup
    
      repeat
        repeat ch from 2 to 0
          fade_down(0, PIXELS-1, ch, 2000)
    
    
    pub fade_down(first, last, ch, ms) | level
    
    '' Fade one channel from 100% to 0%
    '' -- channel is 2..0 (RED, GRN, BLU)
    '' -- ms is total duration of fade
    
      ch <<= 3                                                      ' convert ch byte to bits
      ms := ((ms * 1000) >> 8) #> 50                                  ' convert to us, divide by 256
    
      repeat level from 255 to 0                                    ' 100% to 0%
        strip.fill(first, last, level << ch)                        ' set color
        time.pause_us(ms)                                           ' hold
    
  • Jeff HaasJeff Haas Posts: 421
    edited 2016-09-27 00:04
    I just got a chance to try this. Works great!

    Thanks again.
Sign In or Register to comment.