Hello!
I’ve been having a wonderful time working with the PixelBlaze V3, building some custom controllers for wearable LED suits for an outdoor event coming up.
This evening, I ran into a little snag. I’ve been writing all my code on one PixelBlaze (firmware 3.16), and tonight for the first time I went to install it on a second one (firmware 3.18)… to no avail. I still get “Looks OK, pattern is live!” though there’s nothing actually being displayed on the pixels.
So my question is - are there any known code-breaking changes between 3.16 and 3.18? Full code is below, but it’s ~600 lines… a bit of a doozy.
I’ve tried copying and pasting code between the two extant PixelBlazes, as well as exporting and opening the pattern, same result. The new 3.18 PixelBlaze will run a demo pattern just fine (e.g. by hitting New Pattern) so I know I have the pixel type right, decent power etc.
It’s possible there’s something other than the firmware difference causing this, that’s just what I noticed.
var USEFAKEDATA = true
var USESMALLDATA = true
var MODECOUNT = 18
pixelCount = 60
//This will hold all of our imported DMX data
export var frequencyData = array(32)
//These are the variables our DMX data will be translated into
//in the beforeRender function
export var patternSelect = -1
export var patternIndex = -1
export var color1 = array(3)
export var color2 = array(3)
export var color3 = array(3)
export var speed = -1
export var masterBrightness = -1
export var blockSize = -1
export var reversedData = 0
export var rev = 1
var previousPattern = -1
//The final output RGB values in some situations
var _R, _G, _B
//pattern specific variables:
export var pulsePosition = 0
var NUMTWINKLIES = 10
var MAXTWINKLIES = pixelCount
var twinkliePos = array(MAXTWINKLIES)
var twinklieVal = array(MAXTWINKLIES)
var values = array(100)
var fadeSpeed = array(100)
//beforeRender and Render functions:
beforeRenders = array(MODECOUNT)
renderers = array(MODECOUNT)
export function beforeRender(delta) {
if (!USEFAKEDATA){
patternSelect = frequencyData[0]<<8
masterBrightness = frequencyData[1]<<8
if (!USESMALLDATA){
speed = frequencyData[2] << 8
blockSize = round((frequencyData[3] << 8)*10)
reversedData = frequencyData[4] << 8
color1[0] = frequencyData[5]<<8
color1[1] = frequencyData[6]<<8
color1[2] = frequencyData[7]<<8
color2[0] = frequencyData[8]<<8
color2[1] = frequencyData[9]<<8
color2[2] = frequencyData[10]<<8
color3[0] = frequencyData[11] << 8
color3[1] = frequencyData[12] << 8
color3[2] = frequencyData[13] << 8
}
else {
speed = .2
blockSize = 1
reversedData = 1
color1[0] = 1
color1[1] = 0
color1[2] = 0
color2[0] = 0
color2[1] = 1
color2[2] = 0
color3[0] = 0
color3[1] = 0
color3[2] = 1
}
if (reversedData > .5) rev = -1
else rev = 1
patternIndex = floor(patternSelect*MODECOUNT)
}
else {
fakeData();
}
if (patternIndex != previousPattern){
transition(patternIndex)
previousPattern = patternIndex
}
beforeRenders[patternIndex](delta)
}
export function render(index) {
if (patternSelect == -1){_R = 0; _B = 0; _G=0}
else renderers[patternIndex](index)
}
function transition(newPattern){
if (newPattern == 11){
for (i = 0; i < NUMTWINKLIES; i++){
twinkliePos[i] = round(random(pixelCount))
twinklieVal[i] = random(1)
}
}
else if (newPattern == 12){
twinkliePos[i] = round(random(pixelCount))
twinklieVal[i] = random(1)
}
else if (newPattern == 13){
twinkliePos[i] = round(random(pixelCount))
twinklieVal[i] = random(2)
}
else if (newPattern == 16){
for (i = 0; i < pixelCount; i++){
values[i] = 5
fadeSpeed[i] = random(2)*random(3)+.7
}
}
else if (newPattern == 17){
for (i = 0; i < pixelCount; i++){
values[i] = 0
fadeSpeed[i] = random(2)*random(5)+.5
}
}
}
beforeRenders[0] = (delta) => {}
renderers[0] = (index) =>{
rgb(0,0,0)
}
//solid color
beforeRenders[1] = (delta) => {}
renderers[1] = (index) => {
var intensityScale = .7
_R = color1[0] * masterBrightness * intensityScale
_G = color1[1] * masterBrightness * intensityScale
_B = color1[2] * masterBrightness * intensityScale
rgb(_R, _G, _B)
}
var _colorSelect
var _selector
//2 color pulse
beforeRenders[2] = (delta) => {
_selector = wave(mod(time(speed*speed*2)+.125, 1))
if (_selector < .5){
_colorSelect = 0
}
else {
_colorSelect = 1
}
}
renderers[2] = (index) => {
if (_colorSelect == 0){
_R = color1[0] * masterBrightness * wave(time(speed*speed))
_G = color1[1] * masterBrightness * wave(time(speed*speed))
_B = color1[2] * masterBrightness * wave(time(speed*speed))
}
else {
_R = color2[0] * masterBrightness * wave(time(speed*speed))
_G = color2[1] * masterBrightness * wave(time(speed*speed))
_B = color2[2] * masterBrightness * wave(time(speed*speed))
}
rgb(_R, _G, _B)
}
//3 color pulse
beforeRenders[3] = (delta) => {
_selector = mod(time(speed*speed*3)+.0833, 1)
if (_selector < .333){
_colorSelect = 0
}
else if (_selector < .667) {
_colorSelect = 1
}
else {
_colorSelect = 2
}
}
renderers[3] = (index) => {
if (_colorSelect == 0){
_R = color1[0] * masterBrightness * wave(time(speed*speed))
_G = color1[1] * masterBrightness * wave(time(speed*speed))
_B = color1[2] * masterBrightness * wave(time(speed*speed))
}
else if (_colorSelect == 1){
_R = color2[0] * masterBrightness * wave(time(speed*speed))
_G = color2[1] * masterBrightness * wave(time(speed*speed))
_B = color2[2] * masterBrightness * wave(time(speed*speed))
}
else {
_R = color3[0] * masterBrightness * wave(time(speed*speed))
_G = color3[1] * masterBrightness * wave(time(speed*speed))
_B = color3[2] * masterBrightness * wave(time(speed*speed))
}
rgb(_R, _G, _B)
}
//Rainbow Chase
beforeRenders[4] = (delta) => {}
renderers[4] = (index) => {
var intensityScale = .7
hsv(time(speed*speed*rev/blockSize)+(index*blockSize)/pixelCount, 1, intensityScale * masterBrightness)
}
//1 Color Meteor
beforeRenders[5] = (delta) => {
if (rev > 0) pulsePosition = (pulsePosition + (delta/400)/(speed*speed)) % (pixelCount * 2)
else{
pulsePosition = (pulsePosition - (delta/400)/(speed*speed))
if (pulsePosition <= -pixelCount) pulsePosition = pixelCount
}
}
renderers[5] = (index) => {
if (rev > 0){
//if (index == floor(pulsePosition)) rgb(1,1,1)
if (index < pulsePosition && index > pulsePosition - pixelCount/2){
var relative = (pulsePosition - index)/(pixelCount/2)
blend(color1[0],color1[1],color1[2],color2[0], color2[1], color2[2], relative, masterBrightness)
}
else if (index < pulsePosition - pixelCount/2 && index > pulsePosition - pixelCount){
var relative = (pulsePosition - index - pixelCount/2) / (pixelCount/2)
blend(color2[0], color2[1], color2[2],0,0,0,relative, masterBrightness)
}
else rgb(0,0,0)
}
else{
// if (index == floor(pulsePosition)) rgb(1,1,1)
if (index > pulsePosition && index < pulsePosition + pixelCount/2){
var relative = (index-pulsePosition)/(pixelCount/2)
//rgb(0,1,0)
blend(color1[0],color1[1],color1[2],color2[0], color2[1], color2[2], relative, masterBrightness)
}
else if (index > pulsePosition + pixelCount/2 && index < pulsePosition + pixelCount){
var relative = (index - (pulsePosition + pixelCount/2)) / (pixelCount/2)
//rgb(0,0,1)
blend(color2[0], color2[1], color2[2],0,0,0,relative, masterBrightness)
}
else rgb(0,0,0)
}
}
var t_R, t_G, t_B
var prevPosition
beforeRenders[6] = (delta) => {
var changeColor = false
if (rev > 0) {
pulsePosition = (pulsePosition + (delta/300)/(speed*speed)) % (pixelCount * 2)
if (prevPosition > pulsePosition){ //wrapped back to beginning
changeColor = true
}
}
else{
pulsePosition = (pulsePosition - (delta/300)/(speed*speed))
if (pulsePosition <= -pixelCount) pulsePosition = pixelCount
if (prevPosition < pulsePosition){ //wrapped back to end
changeColor = true
}
}
prevPosition = pulsePosition
if (changeColor) _colorSelect = (_colorSelect + 1) % 3
if (_colorSelect == 0){
t_R = color1[0]
t_G = color1[1]
t_B = color1[2]
}
else if (_colorSelect == 1){
t_R = color2[0]
t_G = color2[1]
t_B = color2[2]
}
else {
t_R = color3[0]
t_G = color3[1]
t_B = color3[2]
}
}
renderers[6] = (index) => {
if (rev > 0){
//if (index == floor(pulsePosition)) rgb(1,1,1)
if (index < pulsePosition && index > pulsePosition - pixelCount){
var relative = (pulsePosition - index)/(pixelCount)
blend(t_R,t_G,t_B,0,0, 0, relative, masterBrightness)
}
else rgb(0,0,0)
}
else{
// if (index == floor(pulsePosition)) rgb(1,1,1)
if (index > pulsePosition && index < pulsePosition + pixelCount/2){
var relative = (index-pulsePosition)/(pixelCount/2)
blend(t_R,t_G,t_B,0,0,0, relative, masterBrightness)
}
else rgb(0,0,0)
}
}
beforeRenders[7] = (delta) =>{
}
//single color spread from center
renderers[7] = (index) => {
var center = (pixelCount/2)
var t0 = wave(rev * time(speed*speed/(2*blockSize)) + abs(center-index)/(pixelCount/blockSize))
//rgb(color1[0]*masterBrightness*t0,color1[1]*masterBrightness*t0,color1[2]*masterBrightness*t0)
blend(color1[0], color1[1], color1[2], color2[0], color2[1], color2[2], t0, masterBrightness)
}
//3 color spread from center
beforeRenders[8] = (delta) => {
}
renderers[8] = (index) => {
var center = (pixelCount/2)
var t0 = wave(rev * time(speed*speed/5) + abs(center-index)/pixelCount)
var colorRamp = mod(rev * time(speed*speed*3/5) + (abs(center-index)/(2*pixelCount))+.75, 1)
if (colorRamp < .333) _colorSelect = 0
else if (colorRamp < .667) _colorSelect = 1
else _colorSelect = 2
if (_colorSelect == 0){
t_R = color1[0]
t_G = color1[1]
t_B = color1[2]
}
else if (_colorSelect == 1){
t_R = color2[0]
t_G = color2[1]
t_B = color2[2]
}
else {
t_R = color3[0]
t_G = color3[1]
t_B = color3[2]
}
rgb(t_R*masterBrightness*t0,t_G*masterBrightness*t0,t_B*masterBrightness*t0)
}
///3 color marquee
beforeRenders[9] = (delta) => {
t = mod(time(rev * -.1 * speed / blockSize), 1)
}
renderers[9] = (index) => {
intensityScale = .7
var mbis = masterBrightness * intensityScale
if (((index * blockSize)/pixelCount + t) % 1 < .33){
rgb(color1[0]*mbis, color1[1]*mbis, color1[2]*mbis)
}
else if (((index * blockSize)/pixelCount + t) % 1 < .67){
rgb(color2[0]*mbis, color2[1]*mbis, color2[2]*mbis)
}
else rgb(color3[0]*mbis, color3[1]*mbis, color3[2]*mbis)
}
//4 color beltlight chase
beforeRenders[10] = (delta) => {
t = mod(time(rev * -0.02), 1)
}
renderers[10] = (index) => {
var intensityScale = .8
var mbis = masterBrightness*intensityScale
if (((index)/pixelCount + t) % 1 < .25){
mbis = mbis * .5
}
else if (((index)/pixelCount + t) % 1 < .5){
mbis = mbis * 1
}
else if (((index)/pixelCount + t) % 1 < .75){
mbis = mbis * .5
}
else mbis = 0
if (((index*blockSize) / pixelCount) % 1 < .25) {
_colorSelect = 0
}
else if (((index*blockSize) / pixelCount) % 1 < .5){
_colorSelect = 1
}
else if (((index*blockSize) / pixelCount) % 1 < .75){
_colorSelect = 2
}
else _colorSelect = 3
if (_colorSelect == 0){
t_R = color1[0]
t_G = color1[1]
t_B = color1[2]
}
else if (_colorSelect == 1){
t_R = color2[0]
t_G = color2[1]
t_B = color2[2]
}
else if (_colorSelect == 2) {
t_R = color3[0]
t_G = color3[1]
t_B = color3[2]
}
else { //white
t_R = 1
t_G = .6
t_B = .2
}
rgb(t_R*mbis,t_G*mbis, t_B*mbis)
}
//twinklies - pop in, fade out
beforeRenders[11] = (delta) => {
for (i = 0; i < NUMTWINKLIES; i++){
if (twinklieVal[i] <= 0){
twinkliePos[i] = round(random(pixelCount))
twinklieVal[i] = random(1)
}
else{
twinklieVal[i] -= delta*speed*speed * random(3)/ 25
}
}
}
renderers[11] = (index) => {
var anyTwinklie = false
for (i = 0; i < NUMTWINKLIES; i++){
if (index == twinkliePos[i]){
v = twinklieVal[i]
blend(color2[0], color2[1], color2[2], color1[0], color1[1], color1[2], v, masterBrightness)
//rgb(color1[0] * v * masterBrightness, color1[1] * v * masterBrightness, color1[2] * v * masterBrightness)
anyTwinklie = true
}
}
if (! anyTwinklie) rgb(color2[0]*masterBrightness, color2[1]*masterBrightness, color2[2]*masterBrightness)
}
//twinklies - pop in, pop out
beforeRenders[12] = (delta) => {
for (i = 0; i < NUMTWINKLIES; i++){
if (twinklieVal[i] <= 0){
twinkliePos[i] = round(random(pixelCount))
twinklieVal[i] = random(1)
}
else{
twinklieVal[i] -= delta*speed*speed * random(3)/ 25
}
}
}
renderers[12] = (index) => {
var anyTwinklie = false
for (i = 0; i < NUMTWINKLIES; i++){
if (index == twinkliePos[i]){
if (twinklieVal[i] > 0) v = 1
else v = 0
blend(color2[0], color2[1], color2[2], color1[0], color1[1], color1[2], v, masterBrightness)
//rgb(color1[0] * v * masterBrightness, color1[1] * v * masterBrightness, color1[2] * v * masterBrightness)
anyTwinklie = true
}
}
if (! anyTwinklie) rgb(color2[0], color2[1], color2[2])
}
//twinklies - fade in, fade out
beforeRenders[13] = (delta) => {
for (i = 0; i < NUMTWINKLIES; i++){
if (twinklieVal[i] <= 0){
twinkliePos[i] = round(random(pixelCount))
twinklieVal[i] = 1.8 + random(.2)
}
else{
twinklieVal[i] -= delta*speed*speed *(random(1) + 1) / 25
}
}
}
renderers[13] = (index) => {
var anyTwinklie = false
for (i = 0; i < NUMTWINKLIES; i++){
if (index == twinkliePos[i]){
v = 1-abs(1-twinklieVal[i])
blend(color2[0], color2[1], color2[2], color1[0], color1[1], color1[2], v, masterBrightness)
//rgb(color1[0] * v * masterBrightness, color1[1] * v * masterBrightness, color1[2] * v * masterBrightness)
anyTwinklie = true
}
}
if (! anyTwinklie) rgb(color2[0]*masterBrightness, color2[1]*masterBrightness, color2[2]*masterBrightness)
}
//foreground/background melt
beforeRenders[14] = (delta) => {
meltMod = pixelCount / blockSize
t1 = time(speed * speed) // Time it takes for regions to move and melt
}
renderers[14] = (index) => {
c1 = 1 - abs(index - meltMod) / meltMod // 0 at strip endpoints, 1 in the middle
c2 = wave(c1)
c3 = wave(c2 + t1)
v = wave(c3 + t1) // Separate the colors with dark regions
v = v * v
blend(color1[0], color1[1], color1[2], color2[0], color2[1], color2[2], v, masterBrightness)
}
//Rainbow Melt
var meltMod
beforeRenders[15] = (delta) => {
meltMod = pixelCount / blockSize
t1 = time(speed * speed * 2) // Time it takes for regions to move and melt
}
renderers[15] = (index) => {
c1 = 1 - abs(index - meltMod) / meltMod // 0 at strip endpoints, 1 in the middle
c2 = wave(c1)
c3 = wave(c2 + t1)
v = wave(c3 + t1) // Separate the colors with dark regions
v = v * v * masterBrightness
hsv(c1 + t1, 1, v)
}
//pop to color and dither out
beforeRenders[16] = (delta) => {
for (i = 0; i < pixelCount; i++){
values[i] -= fadeSpeed[i] * speed * delta/200
}
}
renderers[16] = (index) => {
rgb(color1[0] * min(values[index], 1) * masterBrightness, color1[1] * min(values[index], 1) * masterBrightness, color1[2] * min(values[index], 1) * masterBrightness)
}
//fade from zero up to full color
beforeRenders[17] = (delta) => {
for (i = 0; i < pixelCount; i++){
values[i] = min(values[i] + fadeSpeed[i] * speed * delta/2000, 1)
}
}
renderers[17] = (index) => {
rgb(color1[0] * min(values[index], 1) * masterBrightness, color1[1] * min(values[index], 1) * masterBrightness, color1[2] * min(values[index], 1) * masterBrightness)
}
//////////////Utility Functions///////////////
function blend(r1, g1, b1, r2, g2, b2, pctIntoXFade, mb) {
r = r1 * (1 - pctIntoXFade) + r2 * pctIntoXFade
g = g1 * (1 - pctIntoXFade) + g2 * pctIntoXFade
b = b1 * (1 - pctIntoXFade) + b2 * pctIntoXFade
rgb(r*mb, g*mb, b*mb)
//return retVal
}
function rgb2hue(r, g, b){
var cMax = max(r, g)
cMax = max(cMax, b)
var cMin = min(r, g)
cMin = min(cMin, b)
var delta = cMax - cMin
if (delta == 0) return 0
if (cMax == r){
return (.1667 * ((g - b)/delta)) % 1
}
else if (cMax == g){
return (.1667 * ((g - b)/delta + .333)) % 1
}
else if (cMax == b){
return (.1667 * ((g - b)/delta + .667)) % 1
}
}
function fakeData() {
patternIndex = 15
color1[0] = 0
color1[1] = 1
color1[2] = 0
color2[0] = .1
color2[1] = .1
color2[2] = .1
color3[0] = 0
color3[1] = 0
color3[2] = 0
speed = .2
masterBrightness = .1
blockSize = 2//frequencyData[9] << 4
reversedData = frequencyData[10]
NUMTWINKLIES = min(blockSize * 3, MAXTWINKLIES)
rev = -1
}