Code for Task #1 - Random Random Roger Roger!

Perfect. Got it.
Is there some reason for scattering the { }s about in that particular way?

Only for readability. The only thing required is ensuring you have matching pairs.

Curly braces are used in many computer languages (specifically those with syntax derived from the “C” language.) to define blocks of code. They’re analagous to BEGIN…END pairs in older languages. People argue endlessly about the proper way to format them.

My take is this: do it in whatever way makes it easiest for you to understand when you come back after not having looked at that code for a while. (It’s a general programming principle – be nice to the next guy. It’s likely to be you!)

I usually follow these rules:

  • Curly braces are optional for one line if statments.
  • The opening brace goes on the same line as the statement that opens it
  • Code below a brace is indented two spaces. (Or more, to your taste.) Everything within a block is indented to the same level.
  • If you open an new block within a block, indent two more spaces. The indentation will always tell
    you clearly which block you’re currently looking at.
  • Closing braces go on a line by themselves, I sometimes break this rule for else statements because it doesn’t impact clarity, and it makes the code shorter. (It’s a good rule of thumb to to keep functional blocks to 1 screenful or less - makes it easier to see what they’re doing.)
  • Never ever freaking ever under any circumstances use tabs to indent, unless you know for certain that your editor replaces them with spaces. Tabs will definitely bork the next guy, who is invariably using a different editor with different tab settings.

Here’s a working example, from the multisegment pattern. (Ignore the code. It’s looking at every pixel to see what segment it’s in, and calling an appropriate rendering function, but it took a lot of setup to get there, and it’s pretty meaningless in isolation. This one is just for the formatting!)

export function render(index) {
  if (index >= segStart[segNumber+1]) segNumber++;

  if (segEnabled[segNumber]) {
    segRender[segTable[segNumber][__effect]](segNumber,segTable[segNumber],index)
  }
  else {
    hsv(0,0,0);
  }
}
3 Likes

Well, here’s what I got so far.

export var hue
export var sat
export var v
export var theLitPixel
export var cycleTime
export var offdwell
export var timeFactor
export var delta // Just throwing out a bunch of variables to look at

export function sliderSpeed(v) {
timeFactor = random(1) * v * 10 // Some kinda slider

}
export function beforeRender(delta) { theLitPixel=floor(random(pixelCount))
cycleTime=delta*random(100) // Goes negative if >= 10,000. Not sure if affects anything, timewise. My attempt at
// imparting randomness to cycleTime/delta

}

export function render(index) {
delta = cycleTime
hue = random(1)
sat = random(1)
v = random(1)
if (index==theLitPixel) {
hsv(hue, sat, v)
}
else
{hsv(hue,sat,0)}}

The random pixel lit, color, brightness and hue was pretty easy. And the results quite nice, especially on a 16 x 16 matrix.

But, It seemed like there had to be a way to introduce a simple time function/duration (then randomize) to values like on-time and off-time, without the wave stuff, but I guess not. This is far as I’ve got at present what with the rest of life, taking care of Mom, fixing cars and houses, and an old brain. Comments welcome!

1 Like

Couple of comments my code and stuff above -

  1. I played with introducing a random factor to overall delta but it doesn’t work the way I had hoped. Values for delta go negative somehow and the desired “slowdown the cycle effect” is not achieved.

  2. I am still not sure how best to introduce time delays in PB language. Seems like folks ~ typically use a wave, right?

  3. Sliders - I did not know how a slider manifest in this arena until I cobbled one together nd voilà there it is in the user interface. I had wondered, why not just define a variable and adjust it in the code… Stupid, huh?

  4. Twinkle - I’m figuring the simplest manifestation is to modulate brightness according to some wave function, right?

  5. Patience - Your patience appreciated. I do not expect to have all answered by you. Working with the language and interface is clearly most helpful. I do find myself trying to puzzle it out on ‘first principles’ rather than copying other’s code, which probably gets in the way.

  6. My handle and background - Why Gandalf? Because I like the character, he has magic but is flawed, he is humane, and he is humble. What’s not to like?. He is an aspirational character in my book.
    My background is in chemistry (lots and lots of spectroscopy) followed by physical product engineering, then energy efficiency consulting, outreach, and lots of quasi-business oriented reports, presentations and such… not so much coding there…
    Re coding - I started with punch cards/Fortran, so I’m getting up there, then Pascal, then lots of pretty much canned code, so that’s my schtick, please bear with. Per the chemistry background I’m pretty much here to model atmosphere, but that’s another story. Cheers.

@Gandalf, I haven’t had a chance to run your code yet.

That’s not quite how to use “delta”. Think of it as a automatically set value, not one you should ever set. Delta is the time it takes to render one round of setting pixels. We discussed this recently. @devoh explored it. That’s part of the time delay solutions.

Yes, sliders are super easy. Kudos to @Wizard for the simple implementation.

There are many ways to “twinkle”, from random to smooth, all manner of ways to do it. We’ll come back to this in a few months likely.

Cool background and welcome… Good to know background of folks so we find a good level of interaction.

Hey, please don’t worry about it. I may give it a try anywho.

Yeah, I figured delta was something I would try to manipulate with a random variable call, scaled, but it blew up and didn’t have a discernable effect on the pattern. The apparent value of delta did go all over the place, tho. !

Check out this thread for an overview of common approaches!

2 Likes

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.