I think that’s doable in code now. Wave 0…1 so you’d have to add the range, offset, and timebase (it’s all math but I admit I don’t know how that last one works)
Yes, it’d be faster if it’s internal, but maybe just adding options to wave? And calling it equivalent?
// beatsin( BPM, low, high) returns an value that
// rises and falls in a sine wave, 'BPM' times per minute,
// between the values of 'low' and 'high'.
function beatsin(bpm, low, high) {
return wave(time(0.91552734375/bpm)) * (high - low) + low
}
Just applying a little arithmetic to wave(). I’ve used something along these lines in a few patterns to build low frequency waves using a time unit that’s easy to think about in terms of how it works with musical tempo. Totally could do without having this as a built-in though.
@wizard, the clock functions need something for sub-seconds… if I could call a function like ClockSeconds for smaller values, like for milliseconds, that would be fine.
Stepping away from graphics entirely, is there anything we can do in the realm of inter-device communication? We have his marvelous situation where there are small inexpensive computers and sensors to do almost any job you can name. Pixelblaze shouldn’t have to do all the heavy lifting on its own!
I’m still new to the microcontroller universe – are there software standards for interdevice data exchange that Pixelblaze can implement? If there’s no existing standard, maybe you could let users configure a GPIO pin for a low speed serial variable get/set (and pattern changing) protocol. Just making the existing websocket protocol available over serial would be useful.
A function that uses the accelerometer to determine the rotational position of a wheel, such as on a bicycle. The PB w/sensor board would be mounted near the center hub with the X and Y axes pointing out toward the rim. The Z axis would be parallel with the axle and would not be part of the equation.
One caveat: since the accelerometer could not be mounted in the exact center of the wheel, there would be some extra force added to both X and Y when the wheel is spinning, which perhaps could be cancelled out mathematically.
The function could return a value between 0 and 1 to represent the angular position of the wheel.
A real round function, preferably with the ability to limit precision.
A playback from memory. Something that will let me pre-calculate (long) patterns and play them back at rates limited only by the hardware.
A “pixel morph” function that lets me specify a beginning value, ending value, and transition rate. Generates a smooth(ed) transition between the two values.
Ability to add an external serial RAM/EPROM or SD for (long) pattern storage.
Quadrature Encoder read - the ability to use an encoder as an input device without having to bit-bang in the script.
The new playlist feature sounds neat. Would it be possible to have a PB configured as an AP and running a playlist, to send pattern name changes to other PBs that are connected to it, so they’re all in sync? Sort of like a subset of Firestorm functionality. I’m currently syncing the timebase & pattern name on my PBs using a separate Arduino in AP mode, but this would completely eliminate the need for that.
Working on some array functions now. I think these can be made from basics like forEach, reduce, sum faster than a reduce version). Sort would be handy too.
I have aliases working too, though these are syntactic hacks. Like myarray.length, myarray.forEach(fn)
After thinking hard about what features I’d actually use regularly, I’d happily trade any number of new high level features for things like this that move loop code that occurs in many patterns down into the system where it executes faster.
Give me a good set of fast primitives, and I’ll happily code whatever other stuff I need!
(Also, if we’re doing arrays, sizeof() would be handy )
You get arrayLength(a) and a.length as an alias/shortcut.
On v3 these array helpers are 2-3x faster than a for(i=0;i<size;i++) { ... a[i] ...} loop. On the other hand it highlights the current lack of closures, you can’t access local vars in the function.
I think that’s the key to adding functions:
If it’s common enough to be used regularly, and will be much faster than doing it in userspace code (as part of a pattern) then the only real question is “is it worth the space it’ll take up?”, since at some point, there are limits and trade-off.
Hi Scruffynerf,
You’re correct that the existing sensor board functions give me enough to data to calculate the wheel position using some trig functions, but a built-in function would eliminate the need for me to replicate that calculation and JS code within every pattern. Also, the calculation might be faster if it was implemented by the PB, which I assume is running compiled code rather than JS.
I do realize that this may not be something that’s useful to a lot of people, but I thought I would throw it out there just in case.
Compiled binary implementations would also be a lot smaller than JS, so we hit those trade-offs after many, many common-ish functions.
Maybe we need a way to side-load binary implementations, though. It would be nice to be able to write something in C on my computer and expose it as a function to my patterns.
Even a JavaScript library would be nice, like a side-table of JS functions which are only compiled into your pattern if you import them by name.
It feels to me like we are trying to solve multiple problems and it’s not clear to me that there is just one solution.
Complex numbers and 2D/3D vectors would be nice. I’d actually settle for the ability to allocate (small) temporary arrays on the stack. (and to declare and use multi-dimensional arrays in the normal a[x][y][z] way.)
I’m not asking for garbage collection or heap management – array() can still be a one time allocation. Even if stack space is severely limited, it’d be nice to be able allocate say, a 2D point to use for temporary calculation in a function without having to use a globally allocated array.