PoleFX Docs

Pixel Streaming

Every PoleFX pole is a network pixel fixture. You can stream your own video or generative content to it from lighting and VJ software, exactly as you would to any other LED product, using standards the industry already speaks:

  • DDP (Distributed Display Protocol)
  • sACN (ANSI E1.31, also called Streaming ACN)
  • Art-Net

This page tells you everything needed to drive a pole directly: the pixel layout, the universe math, the settings on each end, and how to check your work without guessing.

Different from DMX Control

The DMX page covers driving the player's built-in patterns from a lighting console using a handful of channels (brightness, pattern, hue). This page is the opposite approach: you send the actual pixels and the pole displays them.

Which generation is your pole?

There have been three generations of PoleFX pole, and they differ in ways that matter here. This page describes generation 3, the current product.

Gen 1 Gen 2 Gen 3 (current)
LED strips around the pole 8 4 6
Columns of pixels 8 8 12
Strip wiring one column per strip, straight two columns per strip, zigzag two columns per strip, zigzag
Frame size 255 x 8 255 x 8 240 x 12
Streaming protocols sACN multicast sACN multicast DDP, sACN, Art-Net

Generation 3 raised the resolution around the pole from 8 columns to 12, which is where the current 12 pixel image height comes from.

One thing has always been true of every generation: you send a plain rectangular image and the pole deals with its own wiring. Gen 2 and gen 3 strips physically snake back and forth between their two columns, and gen 1 strips do not, but that is the pole's business. Your content never changes shape because of it.

If you have a gen 1 or gen 2 pole, the protocol options on this page may not be available to you and your frame is 255 by 8 rather than 240 by 12. Get in touch and we will tell you what your specific pole supports.

Before you start

You need three things.

Firmware from July 2026 (version 2026.07) or newer. This is a hard requirement, not a recommendation. Everything on this page, including the settings and the diagnostics, arrived in that release. Poles running older firmware do not accept sACN or Art-Net at all and cannot report or change any of these settings. If your poles predate it, update the firmware first.

To check a pole's firmware, open the PoleFX Player web app, go to Settings > Devices, and look at the Firmware column.

The pole's IP address. See below; this is the question people get stuck on.

A clear path to the pole. Your computer must be on the same network as the pole. Wi-Fi will technically work but will drop packets and stutter; use wired Ethernet for anything you care about.

Finding your pole

Poles answer to a name. A pole called "Top Support" is reachable at polefx-top-support.local, so you can usually skip the IP address entirely:

curl http://polefx-top-support.local/json/cfg

The name is your pole's name in lowercase with spaces turned into hyphens, and a polefx- prefix. This works out of the box on macOS, on Windows 10 and newer, and on Linux with Avahi installed. It needs no setup, no server, and no special switch or router: poles answer these lookups themselves. The one limit is that it does not cross a router, so you must be on the same network segment as the pole.

You can also list every pole at once. On macOS:

dns-sd -B _http._tcp local

Each pole also publishes its strip and pixel counts alongside its name, so a discovery tool can size a pole without connecting to it.

Finding your pole's IP address

If names are not working, or you need the address itself, poles also announce themselves on the network several times a second. The easiest path:

Open the PoleFX Player web app and go to Settings > Devices. Every pole the player can see is listed with its IP address, name, and firmware version. That list is built from the poles' own announcements, so it is current and needs no setup.

If you do not have a player on the network, a pole is still reachable, you just have to find it another way:

  • Poles ship with a static IP address, usually in the 192.168.5.x range, and each model has its own default. If you have the paperwork from your installation, the address is on it.
  • Any network scanner will find it. nmap -sn 192.168.5.0/24 from a terminal, or a phone app like Fing, will list the devices on the network.
  • Once you have a candidate address, confirm it is a pole by opening http://<that-address>/json/cfg in a browser. A pole answers with a block of JSON that starts with its name and profile. Anything else is not a pole.
Heads up

Because poles use static addresses rather than DHCP, a pole moved to a different network may not be reachable until its address is changed to match that network. If a pole has vanished, this is usually why.

Connecting a computer straight to a pole

You can plug a computer into a pole with a single Ethernet cable, with no switch and no router. One extra step is needed, and skipping it is the usual reason this appears not to work.

Give your computer an address on the pole's network. Poles use a fixed address and do not hand one out, so with a direct cable your computer will assign itself an unrelated address and the two will not be able to reach each other. Set your computer's Ethernet interface to a manual address on the same network as the pole, for example:

  • IP address: 192.168.5.100 (any free address on that network)
  • Subnet mask: 255.255.255.0
  • Router: leave blank

On macOS that is System Settings > Network > Ethernet > Details > TCP/IP, Configure IPv4 set to Manually. On Windows it is the IPv4 properties of the adapter.

Once the addresses match, everything on this page works over that one cable, including the .local name and streaming itself.

Important

A pole displays whichever source is actively streaming to it. If the PoleFX Player is still sending to the same pole, the two will compete and one of them will simply be ignored. Before streaming from your own software, open the player's web app, go to Output Settings, and set that pole's device to inactive.

The canvas

This is the part worth reading carefully. Get the canvas right and everything else is straightforward.

A pole is a rectangular image. Its width is the length of the pole and its height is the distance around the pole. For a standard pole that image is 240 pixels wide by 12 pixels tall.

Think of it as unwrapping the pole into a flat strip: 12 lines of pixels running the length of the pole, side by side. The first pixel of each line is at the top of the pole. The 12 lines wrap around the pole, so the top and bottom edges of your image are physically adjacent, and content that scrolls off the bottom edge should reappear at the top edge.

Pixel order is ordinary reading order. Start at the top-left, go left to right along the first line, then the next line down, and so on. Three bytes per pixel, red then green then blue.

pixel index = (line around the pole * pole length in pixels) + position along the pole

Do not add a zigzag or serpentine. This is the single most common mistake and it is worth stating plainly. Physically, each LED strip inside a gen 3 pole covers two of the 12 lines and the data path snakes back and forth between them. The pole undoes that for you. Your software should send a plain, straightforward image in normal reading order, and the pole rearranges the pixels internally to match its own wiring. If your software offers a "serpentine", "zigzag", "boustrophedon" or "snake" pixel order, leave it off.

This has been true of every generation, including the older poles whose strips are wired differently. The pole always adapts to the image, never the reverse.

Send linear RGB. Do not apply gamma twice. Each pole has its own gamma setting (default 1.0, meaning no correction). If your software also applies gamma, either turn one of them off or accept the combined result. When colors look crushed or washed out, this is almost always the cause.

Frame size

The frame size depends on the generation, not on the individual pole. There are only two:

Generation Image size Pixels Bytes per frame
Gen 3 (current) 240 x 12 2,880 8,640
Gen 1 and Gen 2 255 x 8 2,040 6,120

Send the full frame every time, even for a shorter pole. Poles come in different physical lengths, and we do not change the frame size to match. A shorter pole gets the same frame with the content scaled to fit inside it, and whatever is left over is sent as zeros. Always the same size, every frame, which keeps every sender and every pole speaking one shape.

If http://<pole-ip>/json/cfg reports a geometry that does not match the table (multiply led.strips by led.pixels by 3 to get the bytes it expects), send what your pole reports. That reading is always the authority for that pole.

Orientation

Pixel 0 is at the top of the pole. The left edge of your image is the top of the pole, and the right edge is the bottom.

This is the part that trips people up, so it is worth being explicit: the image is stored sideways relative to the pole. The pole stands vertically, but its length is the horizontal axis of your image. That means:

  • Content scrolling left to right on your screen travels down the pole.
  • Content scrolling up and down on your screen travels around the pole.
  • Flipping your image horizontally turns the pole's content upside down.

If you are preparing footage, the practical consequence is that you usually want to rotate it 90 degrees. A tall video of a flame or a waterfall has to be turned on its side to run along the pole correctly.

If your content comes out upside down, you have two options. When you are streaming from your own software, flip the image horizontally there. When the content is coming from the PoleFX Player, use the Flipped toggle in that pole's output settings instead, which does the same thing in the vertical sense you would expect from standing in front of the pole.

Choosing a protocol

DDP sACN (E1.31) Art-Net
UDP port 4048 5568 6454
Unicast to one pole Yes Yes Yes
Multicast Yes No No (broadcast works)
Addressed by byte offset universe universe
Universes for a standard pole not applicable 17 17
Best for efficiency, many poles consoles and media servers Resolume and most VJ tools

Use DDP if your software supports it. It carries a whole frame in six packets rather than seventeen, it has an explicit end-of-frame marker so frames never tear, and it is the only one of the three that can multicast a single stream to several poles at once. Software that speaks DDP includes xLights, LedFx, WLED based tools, and the DDP TouchDesigner plugin.

Use sACN or Art-Net if you are driving the pole from lighting or VJ software, which is far more likely to speak those. They are equivalent in practice here. Pick whichever your software supports; if it supports both, either is fine.

sACN is unicast only

Most sACN software defaults to multicast. Poles do not subscribe to sACN multicast groups, so a default setup will send data that never arrives. You must switch your software to unicast and give it the pole's IP address. A standard pole needs 17 universes, and subscribing to 17 multicast groups per pole is exactly the problem this avoids.

Universes

sACN and Art-Net both carry 512 channels per universe. Since a pixel takes 3 channels, a universe holds 170 pixels, using 510 channels. The last 2 channels of each universe go unused so that no pixel is split across two universes.

A standard pole is 2,880 pixels, so it needs 17 universes. The first 16 are full (510 channels each) and the 17th carries the remaining 480 channels.

Generation Universes Last universe
Gen 3 (current), 240 x 12 17 480 channels
Gen 1 and Gen 2, 255 x 8 12 510 channels (exactly full)

Universes must be consecutive, starting at the pole's start universe.

Setting the start universe

Poles default to starting at universe 1, so a standard pole listens on universes 1 through 17.

There are two ways to change it, and they do exactly the same thing.

From the player web app (easiest). Go to Settings > Devices, click Details on the pole you want, and find Streaming protocols. You can turn each protocol on or off, set the start universe, and see live counts of what the pole is receiving. The panel shows how many universes that specific pole needs and which range it is listening on, so you do not have to work it out. Turning a protocol on or off needs a restart; the start universe applies immediately.

Over the pole's own API, which is useful for scripting or when there is no player on the network.

Art-Net software often starts at 0

Art-Net numbers universes from 0, and Resolume and many consoles default there. A pole expecting 1 through 17 that receives 0 through 16 will get 16 of the 17 universes it needs, never complete a frame, and display nothing at all while appearing to be perfectly healthy. Either set your software to start at universe 1, or set the pole to start at 0 using the command below.

To read the current value:

curl http://192.168.5.12/json/cfg

To change the start universe (this example sets it to 0 for Art-Net software that counts from zero) and save it so it survives a reboot:

curl -X POST http://192.168.5.12/json/cfg -d '{"dmx":{"start_uni":0,"sacn_enable":1,"artnet_enable":1},"save":true}'

The start universe applies immediately, with no reboot. Note that sACN cannot use universe 0 (the standard reserves it), so a pole set to 0 is Art-Net only.

You can also turn either receiver off entirely with "sacn_enable":0 or "artnet_enable":0. Those take effect on the next reboot.

The rest of the configuration API

/json/cfg is not limited to these settings. A GET returns the pole's entire configuration, and whatever it returns it will also accept back on a POST, which is what makes it usable as a backup format rather than just an API. It covers the device name and profile, network addresses, ports, LED geometry and gamma, idle patterns, on-pole text, and the protocol settings above.

Two rules the pole enforces, both worth relying on:

  • A change is all or nothing. The pole validates the whole document before applying any of it. If one field is out of range it rejects the entire request with an error naming that field, and nothing on the pole changes. There is no half-applied state to clean up. Values are never quietly clamped to fit.
  • Nothing persists until you ask. Add "save":true to write the change to the pole's permanent storage. Without it the change is live immediately but will be lost on the next power cycle.

A successful response looks like this:

{"ok":true,"applied":3,"saved":true,"save_error":0,"restart_required":false}

A rejected one is an HTTP 400 whose message names the field, for example 1 field(s) rejected, first: start_uni: out of range.

To back up a pole, save the output of a GET. To restore it, POST that file back with "save":true. Because everything the pole reports is also something it accepts, a backup taken from one pole can be pushed to another.

Setting up Resolume

Resolume is a good choice for streaming video content to poles. Some requirements to know before you start:

  • Resolume Arena, not Avenue. Pixel output over Art-Net is an Arena-only feature. Avenue cannot do it.
  • Art-Net, not sACN. Resolume does not support sACN at all.
  • The free demo version does DMX output; it watermarks the video output.

Resolume's own reference for this is its DMX Output and Fixture Editor manual pages.

1. Build the fixture

Open Application > Fixture Editor and create a new fixture.

  • Width 240, Height 12 for a standard pole. Use the sizes from the table above for other models.
  • Distribution: choose plain reading order, going left to right and top to bottom. Do not choose a zigzag or serpentine option. The pole applies its own internal zigzag; adding one here scrambles the image.
  • Color Space: RGB.
  • Gamma: Resolume defaults this to 2.5. The pole's own gamma defaults to 1.0 (off), so leaving Resolume at 2.5 gives you a normal gamma curve overall. Change it only if the result looks wrong.

2. Create the output

Open Output > Advanced... to open the Advanced Output window.

  1. From the Presets dropdown choose New for a blank layout.
  2. Click the + icon and add a DMX Lumiverse. A Lumiverse is Resolume's virtual container for a set of universes.
  3. If you are only doing LED output, select Screen 1 and delete it.
  4. The Lumiverse creates a DMX Fixture automatically. Select it and choose your pole fixture from the Fixture dropdown at the bottom right.
  5. Position and scale the fixture in the Input Selection canvas. This decides which part of your composition the pole samples.

3. Point it at the pole

Select the Lumiverse and set, on the right-hand panel:

  • TargetIP: choose IP Address and type the pole's address. Resolume can also auto-discover Art-Net nodes, but poles do not announce themselves, so enter the address manually.
  • Subnet 0 and Universe 1, to match a pole using its default start universe. Remember that Resolume counts from 0, so its "Universe 1" is the second universe and matches a pole that starts at 1.
  • Auto Span: on. This lets the Lumiverse grow past one universe automatically, which a 17 universe pole needs.
  • Align Output: on. This stops a pixel from being split across two universes. Poles reject packets where pixels straddle a universe boundary, so this must stay on.

4. Settings worth changing

In Preferences > DMX:

  • Network Adapter: pick the interface your poles are on. Sending to the wrong adapter is the most common reason nothing appears. Note that this switches Art-Net input and output together.
  • Output Delay: defaults to 40 ms, which exists to line lights up with projectors. With no projector in the rig, set it to 0.
  • Output Framerate: poles accept up to 60 frames per second.

The Output > Test Card has a moving diagonal line, which makes a flipped or misordered fixture obvious immediately.

Checking your work

Every pole reports what it is receiving. Open this in a browser:

http://<pole-ip>/json/cfg

Look at the info section for sacn, artnet or ddp. The useful fields:

Field Meaning
packets Data packets accepted
published Complete frames displayed. This is the number that matters.
incomplete_frame The sender started a new frame before finishing the last
wrong_universe Universes outside the pole's range
last_bad_universe The most recent one it had to reject
want_uni_first, want_uni_last The range the pole is actually listening on
bad_stride A universe carried the wrong number of channels
malformed Packets that did not parse
stream_busy Another source is already streaming to this pole

If nothing is displaying

packets is 0. Nothing is arriving. Check the IP address, check you are sending unicast rather than multicast, check the network adapter in your software, and confirm your computer can reach the pole.

packets climbs but published stays 0. Data is arriving but frames never complete. This is nearly always the universe range. Compare last_bad_universe against want_uni_first and want_uni_last, and either move your software or change the pole's start universe.

bad_stride is climbing. Your software is packing a different number of pixels per universe. Set it to 170 pixels (510 channels) per universe. In Resolume this is the Align Output setting.

stream_busy is climbing. Something else is already streaming to this pole, almost always the PoleFX Player. Deactivate the pole in the player's Output Settings.

Everything looks right but the image is scrambled. Check that you have not enabled a serpentine or zigzag pixel order in your software.

Limits and behavior

  • Poles accept up to 60 frames per second.
  • A pole displays whichever source is actively streaming. When one source goes quiet for half a second, another may take over.
  • When streaming stops entirely, the pole returns to its built-in patterns after a few seconds.
  • A frame is only displayed once all of it has arrived, so a dropped packet holds the previous frame rather than showing a torn one.