Code for Task #1 - Random Random Roger Roger!

I will walk thru a basic technique in the next few days. Sorry, I’m a bit behind.

Thanks @ Scruffynerf!
Went to edit the post and hit “withdraw”… here it is again -

Believe it or not I am still STUCK in the weeds on this. Between all else (the Rest of Life) I cannot seem to connect these ideas to affecting LED on and off time. Yeah I’ve looked at the stuff… I don’t want to copy other’s code. So, here’s mine and if someone can fill me in on how connect this to actually controlling on/off time that would be GREAT -

export var hue, sat, v, theLitPixel, onDwell, offDwell, plusDelta, twinkletoes

export function beforeRender(delta) {

plusDelta += (delta)

onDwell = 100 + random(2000)
offDwell = 100 + random(1000)
plusDelta = onDwell + offDwell
if (plusDelta > 3200) plusDelta = 0 // Max total cycle is 3,200 Ms, randomized

theLitPixel=floor(random(pixelCount))
hue = random(1)
sat = random(1)
v = random(1)
v=pow(v,2.5)

}

export function render(index) {

if (index==theLitPixel) {
hsv(hue, sat, v)
//twinkle
// hold this for some random time - HOW?
}
else
{hsv(0,0,0)}
// Hold this for some other time - HOW?
}

// hey

1 Like

@JustPete, if @scruffynerf or @jeff don’t beat me to it, I can help you with this code a bit tomorrow. Don’t let it frustrate you - the language has a ton in common with Pascal, and absolutely nothing is going on in there that computers haven’t been doing since the dawn of time.

I’ve been thinking for a while that it would be helpful to give everybody a better understanding of what the Pixelblaze is actually doing when it runs your patterns.

A good mental model gives you an orderly place to store all the details as you learn so you’re not just trying to memorize heaps of random unconnected facts, which is actually a nearly impossible task.

So here’s my first shot at describing what’s happening when a Pixelblaze loads and runs a pattern. Anybody who’s better at making this sort of diagram, or has more complete information, please revise, expand and improve this!

(Of course,the flow is more complicated for the v3, which has two processors, but the same basic idea applies:

The Pixelblaze loads, compiles and initializes your pattern, then it loops forever calling beforeRender() to set up a frame, then render() for each LED, then it performs other behind-the-scenes system tasks.

2 Likes

Just wanting to say you guys are great. At this point my notes are scattered about and all I seem to get is static/sparks for that pattern. Whatever you may do, and whenever… fantastic!

I keep looking for do-is and do-while stuff… and I know that’s a possibility
The timing thing is eluding me for now.

At least its not assembler… we used that for a few simple things, back in the day.

For now, I’m collating some simplified definitions and terms, as follows, in a spreadsheet -

" % "
*=
**
“=”
“==”
“===”
“+=”
“-=”
“++”
“!”
“!=”
abs
array
break
CamelCase
channel
colorPicker
continue
delta
export var
export var

floor
for

h
hsv
index
“index / pixelCount”
LOGICAL OPERATORS and COMPARISONS
Lookup Table
mode
next
pow
random
render(index)
render
rgb
slider
snake_case
time(interval)

xor

I think I know the point I’d like to hint you about.

Using @zranger1’s helpful diagram, notice that this code is inside beforeRender(delta) – which means it will run once between frames. And keep in mind that a typical frame rate is 60FPS, or in other words, you’re running this 60 times per second:

Do you want to check if something is bigger than 3.2 seconds sixty times per second? Probably! But what about those on/offDwells? And aren’t you overwriting the plusDelta you just accumualted delta into right above?

See how that goes for ya.

1 Like

I’ll echo what @zranger1 and @jeff said, and add this:

Don’t think of do while …
That’s a different sort of programming

Keep in mind the two stroke engine. You don’t want it to stall on one of the two operations it does, it should run smoothly 1,2,1,2,1,2…
Trying to make it wait on 2, will only make the engine falter and sputter.

The on/off/twinkle is really all one thing:
The brightness of the light. So think of the problem like this:

Stroke one (BeforeRender):. How bright is the light? All of your timing happens here… Just keep track of the time, and vary the light brightness variable.

Stroke two (Render):. NO calculation here needed except for deciding what pixel is on or off. If it’s the pixel we’re lighting, then it’s brightness is that variable (which could still be 0), or it’s not that pixel, so it’s always 0 (off)

Repeat, repeat, repeat.

In your beforeRender() function: @jeff’s suggestions are good ones.

Near the line theLitPixel=floor(random(pixelCount)), you have is the right idea. You’re selecting the pixel you want to light at frame time. Thing is, unless it’s controlled by your timer, ( if (plusDelta > 3200)...), it will select a new pixel on every frame.

This is what curly braces are all about - they’re just a general purpose mechanism for marking off functional blocks of code. So if you set that piece of code up like this:

  if (plusDelta > 3200)  {
    plusDelta = 0    // Max total cycle is 3,200 Ms, randomized 
    theLitPixel=floor(random(pixelCount))
    hue = random(1)
    sat = random(1)
    v = random(1)
    v=pow(v,2.5)
 }

all the code between { and } will only be executed every 3.2 seconds, which will give you the timing control you’re looking for.

1 Like

Thanks all… @Scruffynerf, @jeff, @zranger1. I really appreciate the input. Will be back @ it in coming days I anticipate an epiphany soon!

Per my above note, not to forget the Wizardly assistance of @wizard himself…! Thanks all!
I have now generated some random code. Seems to do the thing. I limited colors to the blue spectrum to make it more “starlike”. I think I even did the curly-brace thing fairly right. Kudos to @devoh for slider idea and for getting it done wayyyy quicker than me. All things considered, a great exercise.

Here it is -

// Looks like stars, kinda. Limied to blue range. Hue and sat vary within a range. Intensity varies per double-sine-wave function.
// Harmonics, non-randomness or time-outs seem to be observed at low speedranger values.
// Looks nice at high Scintillation Settings
// 480 FPS at 16 Px; 35 FPS at 256 Px

export var SpeedRanger
export var ScintillationRanger
export var timer
export var dwell
export var theOneLitPixel
export var v

export function sliderSpeedRanger(v) {
SpeedRanger = 100 * v + 0.15}

export function sliderScintillationRanger(t) {
ScintillationRanger = t}

var dwell = random(90)

export function beforeRender(delta) {
timer += delta

v = random(wave(wave(time(0.1 * ScintillationRanger))))

if (timer >= SpeedRanger * dwell) {
timer = 0

hue = clamp(random(1),0.45,0.66)

sat = clamp(random(1), 0.4,1.0)

theOneLitPixel = floor(random(pixelCount))

dwell = random(90)

}
}

export function render (index) {

if (index == theOneLitPixel) {

hsv(hue,sat,v*v) 

}
else {

hsv(0,0,0)

}
}

3 Likes

Excellent. I like the limiting to blue approach. Initially I thought to myself, you could do something like that with RGB value instead of HSV, but the variation of brightness intensity would be harder to simulate, so nice choice there.

Nice, @JustPete! And thanks, @Scruffynerf - this really was an excellent task with miles of room for creativity.

Thanks. It’s a tough balancing act, out of the 5 tasks so far, given the constraints of a single strand, I tried to vary enough, and also keep it flexible.

I need to start a feedback thread.

Nice, @JustPete! I found it perfectly comprehensible.

Here’s a tip for anyone who would like to post code formatted as monospace font. You can use a formatting language called Markdown. In markdown we use backticks (`) to surround `inline code snippets`, and three of them on their own line to make a monospaced code block:

``` 
// monospaced code here
```

To get code highlighting, you can add a language name right after the opening backticks:

```javascript
// Highlighted
function { var variable = 1 }
```

Will render as:

// Highlighted
function f { var variable = 1 }

Limited HTML is supported too. This is an <h3>.

2 Likes

To @jeff’s comment, I’ll just add that it is super handy to know at least a few of the more common markdown commands. You’ll find that they work on the vast majority of online forums these days.

Here’s the cheat sheet I used to learn it:

@Jeff @Scruffynerf this is great. Combines with @Scruffynerf’s curly brackets background info really well.

I found that to corral the beginner issues I had to well-organize and present the code. otherwise its too much of a random junk heap of disconnected references. reveals the structure, I think.

Question - Does markdown interface with Notepad ++ ? Or stand alone?

Comment - I just LOVE cheat sheets! Had one for DOS back in the day… two pages, front to back, mostly replaced 600 page tomes of way too much information.

IMHO most things can be accomplished/built (at least started/prototyped) with a reduced set of commands/language/information… the special cases and fine tuning can be learned/accomplished/tested later.

Oh yeah - Here’s my attempt at corralling pertinent JS/Pixelblaze code: There are definitely some holes left… Some things that seem more useful or potentially useful are highlighted -

PixelBlaze JAVASCRIPT Expressions.pdf (130.6 KB)

1 Like

Nice cheat sheet start…

Google “notepad++ markdown” for a few add-ons that support markdown (I don’t use notepad++ or Windows so can’t point to the best one there)

You can install for Notepad++ plugins from its “Plugins/Plugin Admin…” menu.

I’ve used two – Markdown++ and the NPP Markdown Panel. (I’ve been using them for a while. At this stage, both are good and either will do the job. I actually can’t remember why I felt I needed two.)

I used a few hacks I’ve learned over the years. While waiting to twinkle, brightness is negative, and an odd/even brightness scheme to store whether the pixel is increasing or decreasing in brightness

// A bunch of settings that can be customized.
var numColors = 12 // Number of colors to pick from.
// The minimum and maximum speed a single pixel will twinkle.
var minTwinkleDuration = 100
var maxTwinkleDuration = 500
// The minimum and maximum time to wait unti the next twinkle.
var minWait = 10
var maxWait = 500
// Color for the ambient (off) pixels.
var ambientHue = .5
var ambientValue = .01

// Pattern state
var pixel = 0 // Which pixel is twinkling.
var brightness = 0 // The current brightness + twinkling state (see beforeRender() below).
var hue = 0 // The hue of the twinkling pixel.
var twinkleDuration = 400 // The duration of the currently twinkling pixel.

export function beforeRender(delta) {
  // Modify the pattern state as needed.
  
  // If brightness is zero, it's time to pick another random pixel to twinkle.
  if (brightness == 0) {
    // Pick another random pixel to twinkle.
    pixel = floor(random(pixelCount))
    // Select a random hue from the palette.
    hue = random(numColors) / numColors
    // Pick a random duration to twinkle between the min/max time.
    twinkleDuration = minTwinkleDuration + random(maxTwinkleDuration - minTwinkleDuration)
    // Set the brightness to a random negative time between the min/max wait time.
    brightness = -(minWait + random(maxWait - minWait))
    
  // If brightness is negative, we're still waiting for it to light up.
  } else if (brightness < 0) {
    // Remove the wait time that has elapsed since the last loop.
    brightness += delta;
    // If we've reached zero, begin the twinkling.
    if (brightness >= 0) {
      brightness = 1;
    }
    
  // If the brightness is a positive number, increase or decrease the brightness depending on whether it is odd or even.
  } else {
    // If the brightness is odd it is increasing.
    if (brightness % 2) {
      brightness += 2
      // Check if we reached the maximum brightness and set to an even value to begin dimming.
      if (brightness > twinkleDuration) {
        brightness = floor(twinkleDuration/2)*2
      }
      
    // If the brightness is even it is dimming.
    } else {
      brightness -= 2
      // Check if we reached the end of dimming and set to zero to trigger a new random twinkle.
      if (brightness < 1) {
        brightness = 0
      }
    }
  }
}

export function render(index) {
  // If this is the twinkling pixel, light it up
  if (index == pixel) {
    // Clamp the brightness to zero. Below zero we are waiting for the next pixel to start twinkling, so it is dark.
    var value = clamp(brightness ,0, twinkleDuration)
    // Calculate the relative brightness from 0 to 1.
    value /= twinkleDuration
    // Show the chosen pixel at the selected hue and value.
    hsv(hue, 1, value)
    
  // All other pixels are black.
  } else {
    hsv(ambientHue, 1, ambientValue)
  }
  
}
4 Likes

@aaroneous, I’m glad you’re giving these things a shot. I found it a lot of fun, and useful because it gave me an excuse to experiment in directions I never would have while writing “production” code. Hope you enjoy it too!