Digital Display, Yay!

This board is to show, discuss and archive useful combinator- and logic-creations.
Smart triggering, counters and sensors, useful circuitry, switching as an art :), computers.
Please provide if possible always a blueprint of your creation.
SuicideJunkie
Fast Inserter
Fast Inserter
Posts: 123
Joined: Wed Aug 23, 2017 10:17 pm
Contact:

Re: Digital Display, Yay!

Post by SuicideJunkie »

My old, efficient 14-lamp 7-segment display was getting hard to read in the new graphics, so I improved it.

Chonky Font for Boomer Eyes digital display.
7-segment rules, but with the corner lights set to be suppressed when both segments are on to make rounded corners and pointy verticals (Eg: "Seg 1>Seg 2", as compared to the normal "Seg 1 > 0" enable rule, in case you're wondering).
Toggle the state of the "ZRO OFF" constant combinator to suppress leading zeroes in that position.
The decimal point is just a light manually tweaked to be always-on, and is not part of the blueprint.
7-segBold.png
7-segBold.png (223.45 KiB) Viewed 10092 times
Blueprint String

jade52blue
Burner Inserter
Burner Inserter
Posts: 6
Joined: Tue Oct 13, 2020 2:42 am
Contact:

Re: Digital Display, Yay!

Post by jade52blue »

I've been tinkering with a couple chain-able display designs for my computer project. My numeric display is a 7x2light pattern is a little overcomplicated given my 2 constraints of:

1) I want a traveling minus sign on negative numbers
2) I want 3bit RGB color instead of the factorio default color indexes

There is a "cap" blueprint for the final character, and any number of "cells" can be attached to the left. Since there is no "off" digit, the full-display color (0) makes the display black, so for it to display in white the color channel has to be (7)
Numeric-number.PNG
Numeric-number.PNG (466.77 KiB) Viewed 9978 times
I built a binary encoded 60 character font for the alphanumeric display in a 5x7 grid, which was about the smallest i could get it while still having the letters pass my bar for aesthetically acceptable. Some signals are sent to multiple lights. To per-character color this one a 3-bit rgb value is multiplied by 60 and added to the character (hence why each display has its own test unit blueprint), and color (0) is white as well as color (7) since the display can be deactivated with character=59 for whitespace
Alphanum-number.PNG
Alphanum-number.PNG (877.92 KiB) Viewed 9978 times
Alphanum-text.PNG
Alphanum-text.PNG (958.8 KiB) Viewed 9978 times

User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3699
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Digital Display, Yay!

Post by DaveMcW »

With the new 1.1 feature "divide by each", we can simplify multi digit displays.



10-digit-display.png
10-digit-display.png (337.77 KiB) Viewed 9845 times

Delicon
Burner Inserter
Burner Inserter
Posts: 14
Joined: Sun Aug 16, 2020 2:21 pm
Contact:

Re: Digital Display, Yay!

Post by Delicon »

DaveMcW wrote:
Tue Nov 24, 2020 1:34 am
With the new 1.1 feature "divide by each", we can simplify multi digit displays.
What is the new feature that allows divide by each?

User avatar
NotRexButCaesar
Smart Inserter
Smart Inserter
Posts: 1120
Joined: Sun Feb 16, 2020 12:47 am
Contact:

Re: Digital Display, Yay!

Post by NotRexButCaesar »

Delicon wrote:
Wed Aug 18, 2021 6:15 pm
What is the new feature that allows divide by each?
The each signal is now allowed on the right side of combinators.
Last edited by NotRexButCaesar on Fri Dec 03, 2021 4:57 am, edited 1 time in total.
—Crevez, chiens, si vous n'étes pas contents!

Schallfalke
Fast Inserter
Fast Inserter
Posts: 162
Joined: Sun Oct 28, 2018 7:57 am
Contact:

Re: Digital Display, Yay!

Post by Schallfalke »

Thanks to the great DaveMcW 3×5 dot matrix design and posts with formula showing the "magic". Helps me a lot to understand how these things work!

Based on the logic, I have expanded it as my 5×7 dot matrix design. The font is similar (if not exactly) to those used in many dot matrix calculators and printers.
NumericDisplay.jpg
NumericDisplay.jpg (125.99 KiB) Viewed 9126 times
Remarks
The blueprints should work in both vanilla and (most) modded games, even though the above screenshot was taken when having my mod Schall Lamp Contrast, to make the digits much easier to read.



The blueprint book consists of 3 blueprints, as shown in the above screenshot.
  1. Decimal: The yellow (lower) one. Positive numbers only. Range: 0 to 2147483647.
  2. Hexadecimal +: The green (middle) one. Positive numbers only. Range: 0 to 2147483647.
  3. Hexadecimal +/-: The cyan (upper) one. Negative numbers are treated in Two's Complement. 2 extra combinators to handle negative numbers. Range: -2147483648 to 2147483647
Input
Bottom-right-most arithmetic combinator (Any Signal)
Parameters
Bottom-most constant combinator (Colour Signal) [Default as above screenshot, but feel free to adjust it.]

In contrast to DaveMcW, I have removed the "dead pixels" lamps to save up the material cost.
I have also removed the "trimmed leading zeros" feature to save up one decider combinator. (Where such feature will also make the display showing NOTHING if the signal is exactly zero, which I don't like... When I use it on storage, I want it to show an eye-catching "0", instead of an emptiness where I will likely ignore...)

Different Sizes
SchallCircuitScaling.jpg
SchallCircuitScaling.jpg (98.75 KiB) Viewed 9126 times
Also want to make a small ad to my another mod: Schall Circuit Scaling. It allows shrinking the "pixels" (lamps) and combinators to smaller sizes (sub-tile), so occupying less valuable space. I can share the shrinked blueprints if anyone is interested.

SuicideJunkie
Fast Inserter
Fast Inserter
Posts: 123
Joined: Wed Aug 23, 2017 10:17 pm
Contact:

Re: Digital Display, Yay!

Post by SuicideJunkie »

Inspiration struck and over the last week I made a stock compatible 32 character alphanumeric display with individually addressable colours. (Forget the receiver dish logic and wire your own messages in. Perhaps even make a scrolling marquee since that only requires a simple bit shift with this system ;))
Only 4 constants to hold the decoding rules, plus 5 combinators per segment to do the decoding. I've slipped in an extra bitshift 16 between the top and bottom rows to avoid a lot of clicking to send a wire all the way back to the left.
(And it is two rows because you simply can't zoom out any further to see enough characters)

Main display Blueprint:
Airport_display_blueprint.txt
32 seg display output only.
(88.29 KiB) Downloaded 267 times


Demo rig logic is wired up to a Space Exploration data receiver to display ship's name and status, but you can wire whatever you like instead!
I spent 4 combinators per digit translating an amount (Estimated arrival time) into a decimal readout with fixed locations for each digit, but that can probably be done more efficiently.
And a bunch more deciders and math to determine the state of the ship from its pilot console outputs and slap coloured strings down.

SpaceEx ship status encoder:
Airport_display_SX_Ship_encoder_blueprint.txt
Encoder to display ship stats for Space Exploration ships.
(4.65 KiB) Downloaded 246 times
airboard_live.png
airboard_live.png (1.08 MiB) Viewed 8928 times
airboard_eta.png
airboard_eta.png (1.15 MiB) Viewed 8928 times
airboard_stopped.png
airboard_stopped.png (1.1 MiB) Viewed 8928 times
airboard_lost.png
airboard_lost.png (699.18 KiB) Viewed 8928 times
Edit:
Bonus; turns out the way I'd wired it you can feed in individual segment signals as well as the pre-defined character signals. So pie charts are just a decider and a constant to form, plus a bitshift to position them on the display :)
airboard_spinstats.png
airboard_spinstats.png (1.22 MiB) Viewed 8875 times

User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3699
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Digital Display, Yay!

Post by DaveMcW »

Here is a 10-digit domino display, using only 4 combinators.



domino.jpg
domino.jpg (86.46 KiB) Viewed 8221 times

SuicideJunkie
Fast Inserter
Fast Inserter
Posts: 123
Joined: Wed Aug 23, 2017 10:17 pm
Contact:

Re: Digital Display, Yay!

Post by SuicideJunkie »

I spent a few days thinking about how you could multiplex multiple digits with fewer than M combinators.
The divide by each, and each modulo 10 part came to me, and I'll use that to save almost 40% on my ETA digit generation :)

But I gave up on the display segment compression bit. Turns out I was too focused on adapting it; I see the logic is in the lamps themselves and the domino nature allows for lamps to never turn off with increasing digit values (aside from the odd/even center which is done with one combinator for the whole set wired separately).

Nice work!

User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3699
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Digital Display, Yay!

Post by DaveMcW »

It is possible to control two digits with one combinator, if you double the size of the dictionary. This reduces the size to 11 arithmetic combinators (+2 constant combinators). Thanks to _RandomComputerUser_ for the idea.



13-combinator-display.jpg
13-combinator-display.jpg (176.27 KiB) Viewed 6098 times

Technical description:
Convert a number between 00-99 into a bitmask, with one bit between 0-9 turned on, and one bit between 10-19 turned on. Use the bitwise OR operator to combine the bitmask with the dictionary values, if anything doesn't match the lamp turns off. There is a special case for zero, since the bitmask is 0 it will always match. So the center lamp turns on only if the bitmask is greater than zero.

adam_bise
Filter Inserter
Filter Inserter
Posts: 346
Joined: Fri Jun 08, 2018 10:42 pm
Contact:

Re: Digital Display, Yay!

Post by adam_bise »

Here's the same display applied to train stops for a radar-free map display.
0.png
0.png (26.16 KiB) Viewed 5871 times

User avatar
Nexarius
Filter Inserter
Filter Inserter
Posts: 271
Joined: Sat May 09, 2015 7:34 pm
Contact:

Re: Digital Display, Yay!

Post by Nexarius »

adam_bise wrote:
Sat Feb 05, 2022 7:35 pm
Here's the same display applied to train stops for a radar-free map display.

0.png

lol thats so cool

How is the UPS with that?

aphorisme
Manual Inserter
Manual Inserter
Posts: 1
Joined: Wed Jul 20, 2022 9:13 am
Contact:

Re: Digital Display, Yay!

Post by aphorisme »

Hello there!

So, I'm working on some train network and agreed that I need some encoding for the reservation system, when I remembered these magic number displays from years ago ... I decided to dig into it and understand them and see, if I can use them in other ways. Explaining is the last step of understanding, so I will use this thread to give some explanation how the magic-bits work.

32-bit signed integers

First of all, the numbers of the signals in factorio's circuit network are 32-bit signed integers. This is important to understand, because we want to manipulate these numbers on a bit level.

32-bit just means, that we have 32 zeroes and ones to encode a number. Signed means (in the standard) that the highest bit denotes whether the number is positive or negative:

Code: Select all

0000 0000 0000 0000 0000 0000 0000 0011
The highest bit (on the left) is 0, denoting a positive number. The rest is a bunch of zeroes, ending with 0011, which encodes 3. So, above is the bit representation of the number 3.
Wait, why 3? Well, according to standard. Ignoring positive and negative numbers for a second, how we usually encode numbers into binary is switching the base of a positional system https://en.wikipedia.org/wiki/Positional_notation. I.e. from a base-10 to a base-2.

So, e.g. the number 0011 in base-2 is 2^3 * 0 + 2^2 * 0 + 2^1* 1 + 2^0 * 1 = 2 + 1 = 3 in base-10.
Since we have bits here, I also say "the bit is set" for "the bit is 1" or "the bit is not set" for "the bit is 0". Think of it like a switch. Switch on: set. Switch off: not set.

Negative representation

As I said, the highest bit decides whether the number is positive or negative. But don't get fooled. Since almost forever, just flipping the highest bit to 1 does not invert the number to its negative. E.g.

Code: Select all

1000 0000 0000 0000 0000 0000 0000 0011
is not -3 but actually -2^31 * 1 + ... + 2^1 * 1 + 2^0 * 1 = -2147483645 following what is called two's complement.

How and why is open for you to explore; here it is only important to understand (or accept) that having a bit representation with the bits numbered from 31 to 0, i.e.

Code: Select all

b31 b30 b29 ... b2 b1 b0
can be turned into (the common) base-10 by the formula

Code: Select all

-2^31*b31 + 2^30*b30 + 2^29*b29 + ... + 2^2*b2+ 2^1*b1 + 2^0*b0
Notice the negative -2^31 at the beginning and how it's still true that if and only if this bit (bit b31) is 1, the number is negative, since 2^31 is bigger then all other positions summed up. It is just another negative number then the one you would get when following the naive approach.

Bit shifting

We have everything here to explain the bit manipulation we need for the display magic: bit shifting. Bit shifting shifts all bits of a number for a given amount to the left or right. We stick to left bit shifting here. An example (with less then 32 bits, but it is all the same):

Code: Select all

00101011 << 2 = 10101100
Bit shifting 0010101 for two positions to the left just moves all the bits two to the left and fills 0 from the right: 10101100.

This is completely independent of the "actual" number which is represented here. While bit shifting, we pretend there is no number, there are just bits we manipulate. Of course, after bit shifting, we can just decode a number out of the new bit representation again, since its just another 32-bits, it has to be a number!

A single lamp

Let's say we want a lamp (in factorio) which is turned on whenever :A: is either 1 or 3. The brute-force approach would be probably having two decider combinators, each outputs :Green: = 1, first if :A: = 1, second if :A: = 3. Lamp then is on, whenever :Green: = 1.

But hey, we learned about bit shifting and bit representation and all that ... and a number has 32 bits. What info do we need?
  1. A is 1
  2. A is 3
  3. A is neither 1 nor 3
Not so much information, right? Should fit into 32 bits?

The marker bit

The highest bit in the signed integer representation decides whether the number is < 0 or >= 0. We saw that. But this is something we can check in a decider combinator! If :A: < 0 then the highest bit of the bit representation of signal :A: is set. If :A: >= 0, then it is not set.

To state it again: With a decider combinator, we can check whether the highest bit is set or not.

Putting it together

Now, add bit shifting to the mix. Say, we want to check whether bit 20 is set, e.g. on the following 32-bit signed integer:

Code: Select all

0000 0010 0001 0000 0100 0000 0000 0000
             ^--- bit 20
We shift this such that bit 20 is the highest bit, i.e. shift it 31 - 20 = 11 times to the left:

Code: Select all

1000 0010 0000 0000 0000 0000 0000 0000
^--- was bit 20, now bit 31
If the resulting number is < 0, then bit 20 was set in the original number!

Or in general: having a number, bit shifting by 1 and checking whether the number is < 0 tells us if bit 30 was set, bit shifting by 2 and checking tells us if bit 29 was set, etc.

So, with our single lamp, we want to notice if :A: = 1 or :A: = 3.
Here is the idea: Let's craft a bit representation which has the highest bit set if and only if we bit shift it with 1 or with 3. Hence, when we bit shift by :A: and it is 1 or 3, we have a number < 0. Otherwise the number is >= 0 and therefore we can decide whether :A: was 1 or 3!

As we bit shift to the left, we need the following representation:

Code: Select all

0101 0000 0000 0000 0000 0000 0000 0000
Bit shifting by 1 puts bit 30, which is set, to bit 31, which is then set and hence: a negative number.
Bit shifting by 3 puts bit 28, which is set, to bit 31, which is then set and hence: a negative number.

Every other shift just puts a 0 to the highest bit. Non-negative! ( ... well, what about any :A: > 31? ... see below)

This is the bit representation we are looking for. The final step is, to translate this into a number, since we cannot enter a bit representation in factorio's combinators. Well, we know already how: the sum of the positions. Which is, leaving all the 0s out:

Code: Select all

2^30 * 1 + 2^28 * 1 = 1342177280
This is our magic number, which gets < 0 if and only if bit shifting by 1 or by 3.

Finally: Set the lamp to activate on :Green: < 0. Input is on :A:, have a constant combinator with :Green: = 1342177280, and an arithmetic combinator which bit shifts :Green: << :A: into :Green:. Output of this arithmetic combinator goes to the lamp.
Wait! :A: = 33 make the lamp go on as well. Yes, I lied about the if and only if. Bit shifting in factorio works "in rounds". Going 33 to the left takes the bits one full round to their original position (shifting 32 times) and then one more. Hence, it is like shifting it by 1. (I know, modulo etc. pp. But the "rounds" picture is more helpful if one does not know modulo.)
You promised less combinators then the brute-force approach! But here we have two as well.

Did I? Well, anyways, the thing to notice here is, that the brute-force approach needs as much combinators as you want numbers the lamp has to go on for. Lamp on for 1, 3, and 5? Three combinators. With the bit-shifting approach, only the magic number changes.
Test your understanding: Can you work out the circuits such that the lamp goes on for :A: = 1, 3, 21 or 30?
From lamp to lamps

Let's focus on the number 0 to 9. We want a display which correctly displays each of these numbers, whenever :A: is that number. With the explanations so far, this is pretty close. Maybe you can work it out already ... ?

Our display is made out of lamps, 3x5, and I write A for "lamp on" and O for "lamp off". For :A: = 9 we want:

Code: Select all

A A A
A O A
A A A
O O A
A A A
and for :A: = 8 we want

Code: Select all

A A A
A O A
A A A
A O A
A A A
with the idea from above, we can work out for each lamp a magic number, such that for any possible :A: = 0 to 9, it is either on, when part of the symbol of the digit, or off otherwise, using bit shifting. We just look at the numbers, 0 to 9, if the lamp has to be on. If so, we have to set the respective bit in our magic number, resulting in a magic number which is negative whenever it was bit shifted by any of the respective numbers.

But how do we implement this in factorio's circuits? If we just output everything into :Green:, the signals overlap and the information is lost. The idea is to use a different channel for every lamp. Starting from left to right, top to bottom, we can use the channels :0:, :1:, ... :B:, :C:, ... or which ever we like, such that each lamp has its own channel, i.e. the condition :0: < 0, :1: < 0 etc.
For each channel (and lamp) the constant combinator needs to output the respective magic number.
Hence, we have on :0: a magic number, which gets < 0 whenever it is bit shifted by any number the lamp has to go on for. The same with all the other channels and their lamps respectively.

And that's it. That is all the magic.

Less channels
If you work out the patterns for each lamp on each of the digits 0 to 9, you will notice that some lamps share the same pattern. They go on or off for exactly the same digits. If we use the approach from above, we will have some channels with the same magic numbers, yielding the same results. So, what we can do, we can just let them use the same channel.

Not every lamp needs its own channel; but every unique pattern needs its own channel.

Numbers and digits
The rest of the circuitry you see in the magic-bit solution of displays takes care of the position of the digits you want to display. Say, we have the number 123 as input on :A: and three displays, where the first should display 1, the second 2 and the third 3. We already have the logic for displaying the digits themselves, 1, 2 and 3 (see above). What we need is to extract the hundreds, tens and singles out of 123 and feed it into our display logic.

Well, this is just some integer division foo and using, what is called modulo operation.

Having an integer we can get the the hundreds by dividing by 100 and taking modulo 10. For example:

123 / 100 = 1
1 % 10 = 1

The tens, by dividing by 10 and taking modulo 10:

123 / 10 = 12
12 % 10 = 2

The singles by dividing by 1 and taking modulo 10:

123 / 1 = 123
123 % 10 = 3

I.e. the dividing puts the digit we want to extract to the right-most position, modulo 10 then extracts that right-most position (since we are in base-10 ... but it is okay to just accept that fact).

The end.

I hope that this provides you with the knowledge (or at least some basic grasp) of how to implement such displays on your own. With 32 bit integers, this method can be used to encode 32 different states. So add some letters as well! Or maybe extend it somehow to more states with other channels and a combinator or two? I, for myself, use it, to make train reservations, where each station gets a unique number. Setting the respective bit says: Hey! I'm station 21 and I need a train! And with some bit shifting, I can work out which stations need a train.

Thanks a lot for the cool ideas, for the blueprints and excel spreadsheets. Credits to them! Especially DaveMcW.

Amarula
Filter Inserter
Filter Inserter
Posts: 509
Joined: Fri Apr 27, 2018 1:29 pm
Contact:

Re: Digital Display, Yay!

Post by Amarula »

adam_bise wrote:
Sat Feb 05, 2022 7:35 pm
Here's the same display applied to train stops for a radar-free map display.
Very cool display thank you!
Counting my rocket launches...
Launch count display.png
Launch count display.png (25.86 KiB) Viewed 4611 times
My own personal Factorio super-power - running out of power.

SuicideJunkie
Fast Inserter
Fast Inserter
Posts: 123
Joined: Wed Aug 23, 2017 10:17 pm
Contact:

Re: Digital Display, Yay!

Post by SuicideJunkie »

A self-calibrating analog clock!
The module to the left side detects sun-up via the accumulator (first chargeup is ignored so construction order doesn't impact the numbers)
The calibration module then detects the day length and adjusts the start time, and the indicator starts rotating!

Self-Calibration allows the clock to be built on any space exploration planet and get a to-the-tick day correction for day length! The indicator will rotate faster or slower to match the planet.

As a 12 hour clockface, the indicator goes around once while yellow during the main day, and once while blue as for the night hours.
clockF1.png
clockF1.png (417.45 KiB) Viewed 4217 times
Once the 3rd light is lit the calibration module can be deconstructed and the clock will continue with its current settings.
clockF3.png
clockF3.png (512.73 KiB) Viewed 4217 times
blueprint string

Post Reply

Return to “Combinator Creations”