Here's code for scrolling text across a matrix

I appreciate it!

I’m using your original code I believe: https://pastebin.com/guhUrRYa
The code for my map, which is the original Matrix example provided: https://pastebin.com/xy7sRrsS

OK, got it!

First we will need to reconfigure the map and the code for the fact that you have more LEDs.

In your pattern code, change:
var matrixCols = 8

to the number of columns in your matrix.
var matrixCols = 32

In your map, set
width = 32

Also be sure that your settings tab has the total pixels at 255 (edit: should be 256).

Ok - let’s start with that and see what the pattern looks like!

2 Likes

I’ve been playing with my PixelBlaze and a couple of 8x8 matrices this afternoon. I was getting the same issue as @Kenzillla. For me, changing line 100 from this:

if (renderBuffer[row][col]) hsv(0.07, 0.5, 1) // warm white

to this:

if (renderBuffer[row][col])
  hsv(0.07, 0.5, 1) // warm white
else
  hsv(0, 0, 0)

Did the trick! Hope this helps.

3 Likes

All in all success!

My matrix seems to be arranged with a width of 8, so I left it unchanged.

What I did have to change was inverting the array axes to:

export function render2D(index, y, x) {

This did the trick!

I’ve had it set to 256 pixels. 255 leaves one pixel as ‘always on’ seemingly

Thank you guys so much for the help!! I’ve got DAFT PUNK scrolling across at the moment hah

1 Like

I’m a complete newbie when it comes to PixelBlaze, however I’ve had many years of playing around with LEDs (and coding) so I’ll take a wild stab in the dark that your mapping function is wrong. I have two 8x8 matrices, side by side, the width is 16 and the height 8. I had to write my own mapping function as these don’t zig zag… But that makes the function even easier!

You may want to have a look at that function so that you can get things in the correct orientation. I ended up writing a “pattern” that would just light an individual pixel so that I could work out how it was arranged.

Glad that I could help.

2 Likes

I’ve been doing some work with the code that Jeff posted, mainly changing the font and also looking to get a 5x7 font working so it can exactly emulate a old “moving message display” that I have (it’s working but needs some tidying/optimising) and I noticed a bug in the code! Line 146 in the original code needs to be changed from:

bit = (((character[row] << colIndex) & 0b1000000) == 0b1000000)

to:

bit = (((character[row] << colIndex) & 0b10000000) == 0b10000000)

There’s a zero missing so it’s using the wrong bitmask and ignoring the first column of each character. I’d spotted the issue before but just put it down to the font. Now I’ve finally tracked it down! :grinning:

Hope this helps!

3 Likes

I had the same issue as well! I was wondering why my custom characters were getting truncated, but just chalked it up to it being more readily formatted for 7x7 chars. All that really remains is for me to try and figure out how to insert some variable kerning between each character at some point

1 Like

This is on my list of things to do! I had a 5x7 font working but I appear to have lost the code! :frowning: I shall recreate it over the next few days and make sure that I keep it somewhere safe!

@jeff

Hi Jeff,

I found yours “scrolling text” pattern and playing with it now.
My matrix is flex 8x32 but wired in zigzag vertically.
So, I am using “Multiple Matrix” mapping tub/function, adjusted
settings accordingly and mapping looks good.
Text is also scrolling right-to-left, characters looks good
but … up side down!
Is it any variable which may control row indexing order or it
should be reversed manually or mapping is not quite right?

Hey! I coded it for the computer graphics convention where (0, 0) is in the top left with positive Y pointing down. Most 2D patterns will work best if your mapping is for this convention as well - you can confirm it’s mapped correctly if the mapping helper pattern has it’s curve radiating from the top left.

One quick hack is to just invert Y in your map generator code. So, if you see something like push([x, y]) in the Mapper tab, just change it to push([x, -y]).

If for some reason you really don’t want to change the map, you can always do the same Y axis inversion just inside the render2D(index, x, y):

y = 1 - y

I am using “Multiple Panel Matrix” from Mapper tub.
This version does not use push([x, y]) Instead it uses map.push(p) in the
function panel(w, h, sx, sy, angle)

I tried this method but it generates error message “Array index out of bound”.

My matrix is 8x32 but it zigzagged vertically instead of horizontally.
When I adjusted configuration in the Mapper dots are scrolling left to right
but wave is moving in opposite direction.
I guess, this is a problem.

Also I have a question about mapping code.
How do I save changes and where?
Do I have to copy-paste mapping code into pattern (at the end)?

PS.
I just noticed, after running for a while somehow it fixed itself on its own.
However very bottom line is one step behind.

Thanks, I understand now - the “Multiple Panel Matrix” is a recent new template.

I’m guessing that sometimes your y is equal to 0, which makes the array index 1-too-many. A very quick fix that will probably fix this error and might also fix your bottom line is to instead do:

y = .9999 - y

and if other index errors persist, the fully safe way is to change:

row = floor(y * matrixRows)

to

row = clamp(floor(y * matrixRows), 0, matrixRows - 1)

There’s a green Save button below the code textarea that persists it to the board.

I also save my maps in separate JS files on my hard drives for my own reference. In adition, if a pattern is particularly tightly coupled to the particular map or install, I’ll sometimes copy the map generator into a multiline comments section in the pattern itself (but this is not common for me).

I am sorry to say this, but both suggested fixes did not work.
First one still generates the same “Array index out of bound” error message.
Second one simply did not change anything.

I guess, my problem is related to not common wiring for my 8x32 matrix.
Instead of zigzagging rows it zigzagging columns.
Another words, y increments first followed by x.
The starting point is the same - Pixel-0 is a top left LED x=0, y=0
Next Pixel-1 is going down, i.e. x = 0, y=1 instead of expected x=1, y=0 and etc.
I think, I have to create my custom mapping.
So, it is time to learn how to do this and improve my programming skills.

Ops, I was looking for this button but somehow missed it.

This is exactly what I am looking for.

I am very confused.
Could you please provide a quick example (or link) how to do this?

Well,
After changing patterns on the same PB all my saved changes disappeared.
What I am doing wrong?

Definitely I need an ability to store mapping per pattern.

Finally I got thing working right.
I had to create JSON style mapping for my matrix.
Once I loaded it into mapper scrolling became functional in a right way.
I tried to create mapping mathematically but no matter what I tried preview
did not look right. What is expected values for x and y?
Are they integers or floats with 0-1 range?

I was able to save my mapping but where this is stored?
It looks like somewhere in undisclosed location with no name and no way
to see it after browser is closed and reopened again.
Because PB does right thing on power up it definitely uses stored mapping.
But how I can see what exactly is used?
Please provide me an example how to store my custom mapping within pattern?

And I have one more question.
I am looking for the best place how I can assign different colors for a different
characters. I am thinking about using message array index.
Am I right or do you have better idea?

The map coordinate units can be anything. In either JSON or generated mode, the coordinates are normalized to world units (a value from 0 to just under 1.0). Your map coordinates can use integers, floats, centimeters, inches, football fields, light years, etc. The only thing that matters is the relative distance between pixels.

You shouldn’t normally need the locations (implementation details), once you save your map the interface will generally do the expected thing and load the source when you visit the mapper tab while the normalized map is used for patterns.

If you are curious, the source of your map is stored at /pixelmap.txt, and the normalized binary representation is stored at /pixelmap.dat

To use your pixel map in a pattern, implement a render2D function and export it. There are some examples in the mapper docs (scroll down on the mapper tab). Also available here.

I tried to modify mapping code from the example:

function (pixelCount) {
  width = 8
  var map = []
  for (i = 0; i < pixelCount; i++) {
    y = Math.floor(i / width)
    x = i % width
    x = y % 2 == 1 ? width - 1 - x : x //zigzag
    map.push([x, y])
  }
  return map
}

I guess, I understand every line in this code but all my attempts to modify it failed.
There was not any errors but the preview pan never looked right.
I have no idea what I was doing wrong.
I will try again carefully. I have to learn how to do this.

Also, I tried to use “Multi Panel Matrix” mapper.
Visually I got a correct results and it looked exactly as my JSON mapping looks.
The scrolling text pattern worked but up side down.
This makes no sense at all. I am scratching my head.
But it is what it is.

I never seen an example how to embed mapping code right into pattern.
@jeff provided some ideas but I am sorry, I did not get it.
It seems to be a better option because could be easier used on a different PBs.

Thank you for the info but these files are not accessible from the GUI.
I am not sure what was wrong but now I recycled power to PB and restarted browser.
Went to the “Mapper” tab and sure, I can see my mapping.

I think some screen shots would help. Are you getting an error message, or it’s just not doing what you want? What is the modified code?

The “scrolling text marquee 2D” pattern looks upright on my mapped panels. It’s possible that your map is upside down in the mapper. The multi panel mapper pattern makes it pretty easy to rotate each panel (and you can make a single one if you like). Pay special attention to the racing dots to ensure they follow the LED wiring.

If that’s still giving you trouble, this one liner will take a 2D map array and flip the y axis, add it just before the return map line:

map = map.map(([x,y]) => [x,-y])

You can even do this to your JSON map if you save it to a variable first, e.g.:

function (pixelCount) {
  var map = [
    [1,2],...
  ];
  map = map.map(([x,y]) => [x,-y])
  return map
}

If in the end you just want to flip the scrolling text pattern, you can change line 99 to this:

row = matrixRows-1-floor(y * matrixRows)

With either that or the map one liner, on my panel here the text is still scrolling from left to right, but is upside down and both cancel each other out and it’s upright again.

This isn’t something you should need to do, especially for a matrix in a fixed configuration. The pixel map describes how the pixels are physically arranged which doesn’t change (except perhaps with something like this).

The mapper type code only works on the editor on the mapper tab. However, if you really want to, you can write your own index to coordinate lookup system in a pattern and implement anything you want. To do that, you wouldn’t implement render2D or render3D, instead doing the coordinate work in a render function. Something like this:

var myMap = [
  [1,2],
  [2,3],
  //...
]

export function render(index) {
  var x = myMap[index][0]
  var y = myMap[index][1]
  //...
}

In this case your (x,y) comes from the map directly, no normalization is done and it’s in whatever units you defined.

1 Like

Today everything works as expected.
But all my yesterday’s attempts were a disaster.
Even thought, the preview window in the Mapper looked nice and clean the pattern
did not work right.
So, yesterday I ended up with creating JSON style mapping.
This was working instantly and exactly as expected.

Today I started fresh and simply replaced JSON mapping with a function
I created yesterday and even tested it with on line JAVA interpreter:

// Mapping for the 8x32 Matrix
// with vertical zigzagging
function (pixelCount)
{
  width  = 32  // Info, this value is not used
  height =  8

  var map = []

  for (i = 0; i < pixelCount; i++)
  {
    x = Math.floor(i / height) 
    y = (i % height)

    // y adjustment for vertical zigzag wiring
    y = (x % 2) == 1 ? (height - 1 - y) : y
    map.push([x, y])
  }

  return map
}

Now this is working just fine!
I wish, I new what was not right yesterday but today everything is OK.

Wow!
Thank you for the link.

Right now I have 2 PBs handy (and few more are on the way).
One is used in pretty much done project for Balcony Lighting.
This one is also integrated with Hubitat Home Automation controller.

I am playing with second PB with different LEDs configuration.
That is why the pattern embedded mapping definitely will help (I think).
So, Thank you very much for the ideas how to achieve this.

I am experienced EE (FPGA area) but now I am slowly gaining more
programming skills while playing with HE, Arduino and PB.
All these projects are 90+% are SW projects.
All related HW is basically ready to go and requires very minor
(if any at all) adjustments (soldering does not count).

For something like that, I imagine pixel count and maybe LED settings would change too, the map is similar. Though you can store a whole program (even with embedded JSON arrays) and use a variable to switch between a few saved modes by going to the editor, change a variable, and save. This way everything is there and only needs minimal manual steps to change to a different LED setup.