pimoroni / unicorn-hat

Python library for Unicorn pHAT and HAT. 32 or 64 blinding ws2812 pixels for your Raspberry Pi
https://shop.pimoroni.com/products/unicorn-hat
MIT License
370 stars 131 forks source link

Added binary_clock.py #115

Closed Pyroseza closed 6 years ago

Pyroseza commented 6 years ago

@Gadgetoid and @IDF31 here's mine, please test and let me know, it works great on my phat (4x8)

Gadgetoid commented 6 years ago

@Pyroseza @IDF31 the string method of converting a number to binary and stepping through each bit is actually unnecessary, since a bitwise AND operator (&) can check if a specific bit in a number is set.

def draw_binary(value, y, color):

    # Our value will be a number <= 59
    # It takes 6 binary digits (bits) to represent all possible values
    # For example: 17 minutes = 0b10001
    # If we step through these binary digits from right to left,
    # this results in the first and fifth pixels being lit.
    for x in range(8):

        # The & operator gives us a result containing all the bits that
        # are set in both values, for example:
        #
        # 1 & 1 = 1 (ie: 0b1 & 0b1 = 0b1)
        # 2 & 1 = 0 (ie: 0b10 & 0b01 = 0b00)
        # 7 & 27 = 3 (ie: 0b00111 & 0b11011 = 0b00011
        if value & 1:
            # Light pixel at x, y if least significant bit is set.
            unicornhat.set_pixel(x, y, color)

        # Shift number right one place, placing the next bit at 1
        # EG: 0b00010 becomes 0b00001
        value >>= 1

This steps through the individual binary digits in a number and draws them least-significant-bit first from left to right.

Pyroseza commented 6 years ago

Elegant I like it, I’ll make the change in a few minutes

Pyroseza commented 6 years ago

@Gadgetoid I have a slight problem with this. By using the fixed width I can set and unset the LEDs correctly, no flashing effect.

If I use your method method, I’d have to run an additional for-loop just to clear all the values. If use unicorn_hat.clear or unicorn_hat.reset it creates a flashing effect. Maybe you can advise another workaround for this? I’m thinking of just setting the LEDs to be off as the loop starts just before the condition check...

Also I don’t know if you’ve run my version of it? I don’t use full 8-bit width. I have a variable length and pass it in as a parameter. I.e On the first row I have 2 4-bit values for month and day, then I have 3 6-bit values for normal right-aligned binary values. The 6 left over LEDs on the left are reserved for the “alarm”. I personally don’t like left aligned binary but I can change my script to cater for that.

Anyway I will update my pull request when it’s working the way I want without a flashing effect

Gadgetoid commented 6 years ago

You don't have to run the full bit-width with my example, you can step through any number of bits and set/clear accordingly:

for x in range(bit_width):
    if value & 1:
        # Set pixel
    else:
        # Clear pixel

    value >>= 1

This will step from right-to-left through the bits of a number and stop when it reaches bit_width.

So March, 03, would be 0b0011 and a 4 bit loop would set the first two pixels on that row, and clear the last two pixels.

Pyroseza commented 6 years ago

doh! okay, making changes now

Pyroseza commented 6 years ago

Alrighty @Gadgetoid and @IDF31 have looky now, I've tested and it works fine

Gadgetoid commented 6 years ago

Looks good, works for me in both Python 2 and 3. Thank you both for your joint effort!