# Serial communication

**URL:** <https://forum.electromage.com/t/serial-communication/1988>\
**Category:** Uncategorized\
**Created:** [February 1, 2022, 9:33pm UTC](https://forum.electromage.com/t/serial-communication/1988 "2022-02-01T21:33:22Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Petros](https://forum.electromage.com/letter_avatar_proxy/v4/letter/p/f05b48/32.png) [@Petros](https://forum.electromage.com/u/Petros)\
**Post date:** [February 1, 2022, 9:33pm UTC](https://forum.electromage.com/t/serial-communication/1988/1 "2022-02-01T21:33:22Z")

</div>

Hi all,

Is there a way to set pixel count via serial communication?

Here’s what I’m trying to achieve:

I’m working on version 2 of [this project](https://forum.electromage.com/t/a-modular-led-light/1731) that’s meant for my kids. Given that they will be removing/adding bricks constantly, I want to find a way to enter the pixel count in settings kind of automatically. The ideal scenario would be to have an Arduino in the enclosure with PB, and when a button is pressed(connected to Arduino) it would do the following:

1. Send command to PB to switch to a pattern with static color.

2. Measure the current. Knowing the LED’s consumption for any given color, it’s easy to calculate how many LEDs are connected.

3. Send that number to PB.

4. Send command to switch to the previous pattern.

I know I’m probably asking for too much but it would be a cool feature to have:)

---

<div class="post-metadata">

**Author:** ![sorceror](https://forum.electromage.com/user_avatar/forum.electromage.com/sorceror/32/735_2.png) [@sorceror](https://forum.electromage.com/u/sorceror)\
**Post date:** [February 1, 2022, 10:54pm UTC](https://forum.electromage.com/t/serial-communication/1988/2 "2022-02-01T22:54:35Z")

</div>

It’s a straight line of LEDs in the end, right?

Suppose you have the PB always sending data for all of the possible pixels (e.g. just black for the pixels beyond the current length), and put the Arduino in a little end block “magic wand”. It just has to read the decrementing-pixel-address out of the serial stream and then it knows _exactly_ how many pixels there are. Tell your kids they have to wave the magic wand (briefly connect the end block) at the end of the brick snake whenever they change it. Or, if price is no object, put an arduino at the end of every block and reconcile “maximum address last mentioned” on the PB.

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [February 2, 2022, 12:11am UTC](https://forum.electromage.com/t/serial-communication/1988/3 "2022-02-02T00:11:09Z")

</div>

Or you could make a max pixelcount (and never change it except thru UI), and then make the ‘real’ pixelcount be a setting in your patterns. (Yes, youd’d have to modify existing patterns, to use yours). The question is how would you populate this value, since each pattern would have to be able to calculate it. If you used the sensor board protocol (documented in the docs for it), you could send a value that could dynamically change based on the number of blocks… and some way to generate serial data (so Arduino, for example). So whether you use the above idea of current measuring, or @sorceror’s idea of a smart end cap, or some other method, you just need to serially send the value back to the PB via the existing sensor board input as a value it’ll be polling for anyway.

---

<div class="post-metadata">

**Author:** ![pixie](https://forum.electromage.com/letter_avatar_proxy/v4/letter/p/7bcc69/32.png) [@pixie](https://forum.electromage.com/u/pixie)\
**Post date:** [February 2, 2022, 1:29am UTC](https://forum.electromage.com/t/serial-communication/1988/4 "2022-02-02T01:29:46Z")

</div>

If you swapped the Arduino for a wifi-enabled chip like the [ESP-01S](https://www.shenzhen2u.com/ESP-01S-ESP8266-WIFI-MODULE) – it’s the same ESP8266 MCU that’s in the v2 Pixelblaze, but in a pico package – you could [send a websocket message to the Pixelblaze](https://www.mischianti.org/2020/12/07/websocket-on-arduino-esp8266-and-esp32-client-1/) to change `pixelCount` in the settings. Or if you don’t want to learn another platform, just [use an ESP-01S as a wifi adapter for the Arduino](https://create.arduino.cc/projecthub/imjeffparedes/add-wifi-to-arduino-uno-663b9e)…same exact same.

To find out what the message would need to contain, open up Developer Tools while the webbrowser has the Settings page loaded, and [look at the websocket message traffic](https://www.youtube.com/watch?v=CGz1-_K2PSw&feature=emb_imp_woyt) while you increment and decrement the number of LEDs.

---

<div class="post-metadata">

**Author:** ![zranger1](https://forum.electromage.com/user_avatar/forum.electromage.com/zranger1/32/301_2.png) [@zranger1](https://forum.electromage.com/u/zranger1)\
**Post date:** [February 2, 2022, 2:59am UTC](https://forum.electromage.com/t/serial-communication/1988/5 "2022-02-02T02:59:17Z")

</div>

I think, rather than try to count ws2812 data bits to figure out how many pixels, I’d try something like running a separate voltage-carrying wire through all the blocks, with a resistor that knocked the voltage down by a specific, easily distinguishable amount per block.

That way, you might be able to use the Pixelblaze’s analog input to read the voltage and calculate the number of blocks pretty easily. Dynamically changing pixel count is another story. Possibly better to just adapt a few custom patterns for these blocks.

---

<div class="post-metadata">

**Author:** ![Petros](https://forum.electromage.com/letter_avatar_proxy/v4/letter/p/f05b48/32.png) [@Petros](https://forum.electromage.com/u/Petros)\
**Post date:** [February 2, 2022, 10:14pm UTC](https://forum.electromage.com/t/serial-communication/1988/6 "2022-02-02T22:14:01Z")

</div>

@sorceror some of the possible configurations are closed-loop and don’t allow any extra bricks to be connected(squares or circles for example), plus the Arduino brick would still have to be wired to the PB box, making it all accident-prone and messy. Your reply though kind of answers another question I have and would be posting in a new thread. Most of the connecting tubes split the output 2,3 or 4 times, I was thinking if there is a way to have a microcontroller in there take the incoming signal, and add 10 virtual less to every output. To make it a bit more clear, index is at say 50 when entering the connecting tube, 1st output starts at 51, 2nd at 61, 3rd at 71. I tried googling it but didn’t come up with anything meaningful. Using SK6812 btw. If you suggest that an Arduino can read the pixel address, then I guess it’s doable?

@Scruffynerf I am using an expander. If I get you right, it’s possible to use the expander’s serial to feed the values from an Arduino, correct? Could you maybe elaborate a bit more?

@pixie I really prefer a hardwired approach to the solution, adding yet another wifi board in the box is something I prefer to avoid, but if I can’t find another solution the board you suggested is super small and as long as I can figure out(google to be precise) how to do a combination of current sensing and sending messages to PB with it, I’ll go this route:)

@zranger1 Great idea but I have no pins left in the connectors for another wire, I’m already current-limited as it is. In addition to that, I’m trying to be kind of backwards compatible and be able to use the bricks I’ve already made for v1.

The problem with saving the pixel count within the pattern is that the value would not persist between resets etc-at least not until Ben adds variable saving in a future release.

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [February 2, 2022, 11:01pm UTC](https://forum.electromage.com/t/serial-communication/1988/7 "2022-02-02T23:01:57Z")

</div>

Correction: I said Expander but meant Sensor Board. I’ve fixed it above

Here’s the details on the sensor board protocol, which you could make your arduino speak

> **[GitHub - simap/pixelblaze\_sensor\_board](https://github.com/simap/pixelblaze_sensor_board)**
>
> Contribute to simap/pixelblaze\_sensor\_board development by creating an account on GitHub.

Keep in mind, there is code to accept the OUTPUT of a sensor board ([https://github.com/simap/PixelblazeSensorBoardLibrary](https://github.com/simap/PixelblazeSensorBoardLibrary)). I’m talking about the opposite: you’d pretend to be the sensor board with your arduino and talk to the PB.

I think the websocket approach is likely cleaner, given your points above, but it’s an option so…  
Wired serial vs wireless

---

<div class="post-metadata">

**Author:** ![wizard](https://forum.electromage.com/user_avatar/forum.electromage.com/wizard/32/4_2.png) [@wizard](https://forum.electromage.com/u/wizard)\
**Post date:** [February 2, 2022, 11:39pm UTC](https://forum.electromage.com/t/serial-communication/1988/8 "2022-02-02T23:39:48Z")

</div>

> [@Petros](#):
>
> I was thinking if there is a way to have a microcontroller in there take the incoming signal, and add 10 virtual less to every output. To make it a bit more clear, index is at say 50 when entering the connecting tube, 1st output starts at 51, 2nd at 61, 3rd at 71.

Yes, definitely possible. I’ve done something like that for a client project (can’t share the code though).

I’ve also head of others doing this and sending config down as fake pixels, so the micro can get configuration about how many pixels to route. That of course would most likely require some modification to PB, or some interesting hackery in the pattern code.

You could hack that with one or more WS2811 IC controlling a signal multiplex without a micro. If you detect this control pixel (which uses no more current, yet consumes 1 pixel of data), then you could steer it by setting R or G or B to 100%.

If you have a micro in each node, it might be easier to use the expander serial protocol instead of ws2812 data, and give each node it’s own single-channel address. Then it wouldn’t matter where they were, they’d still get the same pixel addresses. You’d want to buffer the serial data for each split though to avoid reflections.

---

<div class="post-metadata">

**Author:** ![Petros](https://forum.electromage.com/letter_avatar_proxy/v4/letter/p/f05b48/32.png) [@Petros](https://forum.electromage.com/u/Petros)\
**Post date:** [February 3, 2022, 10:21am UTC](https://forum.electromage.com/t/serial-communication/1988/9 "2022-02-03T10:21:23Z")

</div>

Does PB expect to get such data from the sensor board? So far in the documentation I only see mentions for the sensors, nothing related to pixel count or similar.

---

<div class="post-metadata">

**Author:** ![Petros](https://forum.electromage.com/letter_avatar_proxy/v4/letter/p/f05b48/32.png) [@Petros](https://forum.electromage.com/u/Petros)\
**Post date:** [February 3, 2022, 10:29am UTC](https://forum.electromage.com/t/serial-communication/1988/10 "2022-02-03T10:29:50Z")

</div>

> If you have a micro in each node, it might be easier to use the expander serial protocol instead of ws2812 data, and give each node it’s own single-channel address. Then it wouldn’t matter where they were, they’d still get the same pixel addresses. You’d want to buffer the serial data for each split though to avoid reflections.

Can you please elaborate on how to do this? Is there any documentation available for it? I must admit I’m completely out of my depth with this one, so if I go down this route I’ll have a million questions. Having individual addresses seems to be a great way to solve many issues, but I don’t get how it works if there is no feedback. How does PB understand where the nodes are placed? If you have for example 10 leds in row, then split to 2 or 3 nodes of 10 each, what’s the order, is it based on the address’s number? I guess you’d have to let the expander know how many nodes are connected, correct?

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [February 3, 2022, 1:53pm UTC](https://forum.electromage.com/t/serial-communication/1988/11 "2022-02-03T13:53:52Z")

</div>

> [@Petros](#):
>
> Does PB expect to get such data from the sensor board?

Nope, you’d have to Homebrew it to take some data it did expect and convert to a pixelCount substitute.

You’re really pushing the limits of PB here.

---

<div class="post-metadata">

**Author:** ![Petros](https://forum.electromage.com/letter_avatar_proxy/v4/letter/p/f05b48/32.png) [@Petros](https://forum.electromage.com/u/Petros)\
**Post date:** [February 3, 2022, 5:14pm UTC](https://forum.electromage.com/t/serial-communication/1988/12 "2022-02-03T17:14:58Z")

</div>

Looks like websocket is the way to go, thanks for the explanation.

---

<div class="post-metadata">

**Author:** ![wizard](https://forum.electromage.com/user_avatar/forum.electromage.com/wizard/32/4_2.png) [@wizard](https://forum.electromage.com/u/wizard)\
**Post date:** [February 3, 2022, 6:37pm UTC](https://forum.electromage.com/t/serial-communication/1988/13 "2022-02-03T18:37:22Z")

</div>

> [@Petros](#):
>
> Does PB expect to get such data from the sensor board? So far in the documentation I only see mentions for the sensors, nothing related to pixel count or similar.

Sorry, I meant the output expander, not the sensor board. In combination with what you are using to sense current (which might be a sensor board).

> [@Petros](#):
>
> Can you please elaborate on how to do this?

OK, without a custom micro, consider how this could work with existing output expanders.

If you used an output expander (OE for short) in each node, and used a unique combination of output channel and board address, you could have 64 unique node addresses. Each of those could be configured for a unique range of pixel addresses.

For example, let’s say you have 12 pieces / nodes. You’d need 12 OE. They are all fed off of the same data stream. On the first 8 nodes you would leave the OE addresses set to 0, and connected LEDs to increasing output channels from 0-7. The 9th through 12th nodes would be at board address 1, using 4 channels numbered 0 through 3.

In the PB settings screen, you’d set it up with only 2 boards (one at address 0, one at address 1), and configure the channels for each node. Sure all 8 OE at address 0 are doing the same thing, but only one of the channels is connected at a time.

Let’s say to make the math easy for an example, every node is only 10 pixels long, and on the setting screen, each channel starts at the next address (as it would if you clicked the auto button).

The first node is at board 0, channel 0, and has pixel start index 0, length of 10. It can be drawn in a render when index is 0 through 9.

The next node is board 0, channel 1, and has pixel start index 10, length of 10. It can be drawn in a render when index is 10 through 19.

And so on. You’d have 120 pixels in total, no matter how many nodes were actually connected, and in any order.

It wouldn’t know where in the assembly they are. The order wouldn’t matter (to it) since they have a fixed address, and it would have the same pixel index no matter how many nodes or in what order they were arranged. You could handle those aspects in some other way, this would just be a way to get everything individually addressable and doesn’t have any inherent detection, it’s just output.

If you don’t want to buy and install an OE for each node, but have room for your own micro and lots of free time, you could adapt the output expander code or write you own client that reads the data stream and spits out a single channel for the LEDs.

> [@Petros](#):
>
> How does PB understand where the nodes are placed?

It wouldn’t, not alone. You’d need some other way to detect the order, but to some extent the order wouldn’t matter in that you wouldn’t need it in order to know how to draw things consistently.

In some ways this would make it harder to detect, since turning any given pixel or node on/off changes the current draw by the same amount regardless if where it is, but you could still detect the presence / absence of a node.

---

<div class="post-metadata">

**Author:** ![Petros](https://forum.electromage.com/letter_avatar_proxy/v4/letter/p/f05b48/32.png) [@Petros](https://forum.electromage.com/u/Petros)\
**Post date:** [February 3, 2022, 8:27pm UTC](https://forum.electromage.com/t/serial-communication/1988/14 "2022-02-03T20:27:54Z")

</div>

I cannot fit an OE in the bricks, no way, and going for a micro involves coding skills I simply don’t have, so I’d like to investigate the possibility of modifying the signal within the connectors and changing the index(adding 10 pixels) in the forked output. Any chance you can point me to some sort of documentation or similar? I can’t find anything related to SK6812 protocol or what type of controller I would need to achieve it. I’m willing to invest plenty of time on this but I need to start somewhere:)

---

<div class="post-metadata">

**Author:** ![wizard](https://forum.electromage.com/user_avatar/forum.electromage.com/wizard/32/4_2.png) [@wizard](https://forum.electromage.com/u/wizard)\
**Post date:** [February 3, 2022, 8:34pm UTC](https://forum.electromage.com/t/serial-communication/1988/15 "2022-02-03T20:34:25Z")

</div>

> [@Petros](#):
>
> I can’t find anything related to SK6812 protocol or what type of controller I would need to achieve it.

6 of one, half a dozen of the other. If you have a custom micro doing stuff, then you have about the same amount of work either way.

SK6812 is the same as WS2812, a series of pulses that are either long or short. 24 of these for every RGB pixel. A pause of many microseconds means the data is done. The pulse timing is brutally sensitive though.

For specs, look at any ws2812 / [sk6812 datasheet](https://cdn-shop.adafruit.com/product-files/1138/SK6812+LED+datasheet+.pdf).

---

<div class="post-metadata">

**Author:** ![Petros](https://forum.electromage.com/letter_avatar_proxy/v4/letter/p/f05b48/32.png) [@Petros](https://forum.electromage.com/u/Petros)\
**Post date:** [February 3, 2022, 10:44pm UTC](https://forum.electromage.com/t/serial-communication/1988/16 "2022-02-03T22:44:10Z")

</div>

I’ll play around and see if I can pull it off, if not I’ll try fitting 10 leds in the connector, maybe break the leds and see if the ICs still function:)

Going back to the question of changing the pixel count remotely, I went through the Websocket API docs and didn’t find any mention to it. Is it possible or not? Bear in mind I’m using an expander, so I’d need to change multiple outputs and not only one.

---

<div class="post-metadata">

**Author:** ![wizard](https://forum.electromage.com/user_avatar/forum.electromage.com/wizard/32/4_2.png) [@wizard](https://forum.electromage.com/u/wizard)\
**Post date:** [February 3, 2022, 11:03pm UTC](https://forum.electromage.com/t/serial-communication/1988/17 "2022-02-03T23:03:41Z")

</div>

I wouldn’t change the pixelCount unless you can’t use another variable in the pattern for some reason. I would add something like “detectedPixelCount” and use that (it could default to pixelCount if you like).

Writing pixelCount will re-init the current pattern, and by default causes a write. Same for the output expander settings, which goes hand-in-hand with pixelCount. The map would have to be regenerated in the UI, if you have one.

---

<div class="post-metadata">

**Author:** ![Petros](https://forum.electromage.com/letter_avatar_proxy/v4/letter/p/f05b48/32.png) [@Petros](https://forum.electromage.com/u/Petros)\
**Post date:** [February 4, 2022, 11:29am UTC](https://forum.electromage.com/t/serial-communication/1988/18 "2022-02-04T11:29:38Z")

</div>

I don’t mind having to redo a map if necessary, I hardly ever use them anyway.  
It’s still a bit unclear to me if it is possible to set pixels in the expander settings through web socket, could you please clarify? After putting in the new values I’d have to reload a pattern anyway, something I have to do now as well, I don’t know if it’s meant to work in this way but when I change the pixel values in the settings tab the pattern doesn’t re-initialise so I have to go to the patterns page and select it anew. I would do that easily via web socket.

---

<div class="post-metadata">

**Author:** ![pixie](https://forum.electromage.com/letter_avatar_proxy/v4/letter/p/7bcc69/32.png) [@pixie](https://forum.electromage.com/u/pixie)\
**Post date:** [February 4, 2022, 3:04pm UTC](https://forum.electromage.com/t/serial-communication/1988/19 "2022-02-04T15:04:04Z")

</div>

Looking at the websocket traffic with [Fiddler](https://www.telerik.com/fiddler), changing the pixelCount on the settings tab sends a single websocket message containing the JSON string: `{"pixelCount":100}`. If you have an outputExpander configured, any change to the expander configuration sends both the `pixelCount` message and a binary packet with header values `09 05` containing the updated outputExpander configuration file.

The outputExpander configuration file (also available from the Pixelblaze’s webserver as `http://pixelblazeIP/obconf.dat`) has a header byte of `05`, followed by a 96 byte table for each output expander (8 channels \* 12 bytes/channel).

For example, defining two expanders like this:

 ![image](https://forum.electromage.com/uploads/default/original/2X/5/53133dcb4f05b63acf8a557cc3318cf38ca31d0c.png)

Results in a table like this ((initial magicNumber of `05` omitted to make row data structures line up better):  
 ![image](https://forum.electromage.com/uploads/default/original/2X/7/70f6f1cf4d85ff67ef831fb9e7434ac8d796b0a5.png)

Which can be decoded using the data structures found in the [outputExpander source code](https://github.com/simap/pixelblaze_output_expander/blob/master/firmware/Core/Src/app.c) as follows:

 ![image](https://forum.electromage.com/uploads/default/original/2X/d/d20bbf4ec3d69cb77bacf93e1eee9e160d3217e4.png)

Where:

- `addx|chan` is a packed byte (addx:5|chan:3) combining the expander address and the channel index
- `ledType` is an enumeration with 0=‘notUsed’, 1=‘WS2812B’, 2=‘drawAll’, 3=‘APA102 Data’, 4=‘APA102 Clock’
- `numColors` is either 3 (for R/G/B) or 4 (for R/G/B/W)
- `colorOrder` is a packed byte (R:2|G:2|B:2|W:2) containing four 2-bit numbers indicating the order in the colors appear (0 = first, 3 = 3 last). The possible permutations are: 0x24=‘RGB’, 0x18=‘RBG’, 0x09=‘BRG’, 0x06=‘BGR’, 0x21=‘GRB’, 0x12=‘GBR’, 0xE4=‘RGBW’, 0xE1=‘GRBW’
- `pixelCount` is the number of pixels on this channel
- `startIndex` is the first address in the range to be directed to this channel

As @wizard says, updating the pixelCount will save the new value to the flash chip which can be written a limited (though reasonably large) number of times, so you don’t want to do it unnecessarily; however frequently you calculate the number of pixels, you’ll only want to save it back to the Pixelblaze if it has changed.

---

<div class="post-metadata">

**Author:** ![wizard](https://forum.electromage.com/user_avatar/forum.electromage.com/wizard/32/4_2.png) [@wizard](https://forum.electromage.com/u/wizard)\
**Post date:** [February 4, 2022, 5:13pm UTC](https://forum.electromage.com/t/serial-communication/1988/20 "2022-02-04T17:13:01Z")

</div>

Wow, @pixie going all RE on the files! 👏

> [@pixie](#):
>
> initial magicNumber of `05`

FWIW, thats the file format revision number/code. 5 is the current version, but older versions of PB might have a different format.

The “not used” is the uint32\_t frequency for output clocks, which is currently hard coded for 800khz. The expander almost has support for this, and would fall back to 800khz if any of its channels were ws2812. The new chips can handle 4mbps data streams, but I didn’t get auto baud detection working in time. At 2mbps of input data, it was kind of a mute point as 2+ channels of APA102 @ 800khz can keep up with the data input.

[Next page](https://forum.electromage.com/t/serial-communication/1988.md?page=2)
