pimoroni / pimoroni-pico

Libraries and examples to support Pimoroni Pico add-ons in C++ and MicroPython.
https://shop.pimoroni.com/collections/pico
MIT License
1.32k stars 496 forks source link

Unicorn Pack MicroPython Example #27

Closed goodservers-dev closed 2 years ago

goodservers-dev commented 3 years ago

Hi!

The documentation says that the Unicorn Pack supports use from MicroPython as long as we use Pimoroni firmware. Unfortunately, there doesn't seem to be an example .py file to use to learn how to access the pack. Any idea if this is an oversight? Or is one coming down the line?

Thanks. :-)

Gadgetoid commented 3 years ago

Looks like that's my job for this morning, along with the documentation.

goodservers-dev commented 3 years ago

I reviewed the C file for the Scroll example and wrote something for the Unicorn. Strange thing is that it actually causes the hat to briefly flash, then sometimes results in the first few rows turning blue, and the Pi Pico then stopping to respond and no longer show up on a com channel. Guess I'm doing something wrong, but maybe have found some kind of bug?

"Unable to connect to COM3: could not open port 'COM3': PermissionError(13, 'Access is denied.', None, 5) If you have serial connection to the device from another program, then disconnect it there first. Backend terminated or disconnected. Use 'Stop/Restart' to restart."

goodservers-dev commented 3 years ago

import picounicorn as picounicorn

picounicorn.init() picounicorn.clear() picounicorn.set_pixel(1, 1, 100,100,100)
picounicorn.update()

goodservers-dev commented 3 years ago

In fact if I run...

import picounicorn as picounicorn picounicorn.init() picounicorn.set_pixel(1, 1, 100,100,100)

a few times in a row it latches a block of the lights and the Pi Pico drops off the com port

Gadgetoid commented 3 years ago

Yes we're looking into this- re-initializing the PIO/DMA multiple times is causing a lock up. There was a temporary fix, but it doesn't appear to help!

goodservers-dev commented 3 years ago

Still crashes a lot when using the Pi Pico and is very frustrating as have to keep unplugging and plugging back in again. In the meantime, here is a simple clock to give a little back...

import math import time import picounicorn

picounicorn.init()

w = picounicorn.get_width() h = picounicorn.get_height()

Initial time

digit_a = 1 digit_b = 4 digit_c = 5 digit_d = 6

seconds = 0

Brightness / colour

colour = [0,0,0],[70,0,0],[0,0,20],[0,0,70]

Character m1ochrome pixel map

zero = [1,1,1,1,1],[1,0,0,0,1],[1,1,1,1,1] one = [0,0,0,0,0],[0,0,0,0,0],[1,1,1,1,1] two = [1,0,1,1,1],[1,0,1,0,1],[1,1,1,0,1] three = [1,0,1,0,1],[1,0,1,0,1],[1,1,1,1,1] four = [1,1,1,0,0],[0,0,1,0,0],[1,1,1,1,1] five = [1,1,1,0,1],[1,0,1,0,1],[1,0,1,1,1] six = [1,1,1,1,1],[1,0,1,0,1],[1,0,1,1,1] seven = [1,0,0,0,0],[1,0,0,0,0],[1,1,1,1,1] eight = [1,1,1,1,1],[1,0,1,0,1],[1,1,1,1,1] nine = [1,1,1,0,1],[1,0,1,0,1],[1,1,1,1,1] blank = [0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]

Draw clock characters

def digit(x,y,digit,picker): picounicorn.set_pixel(x, y, digit[0][0]colour[picker][0],digit[0][0]colour[picker][1], digit[0][0]colour[picker][2]) picounicorn.set_pixel(x+1, y, digit[1][0]colour[picker][0],digit[1][0]colour[picker][1], digit[1][0]colour[picker][2]) picounicorn.set_pixel(x+2, y, digit[2][0]colour[picker][0],digit[2][0]colour[picker][1], digit[2][0]colour[picker][2]) picounicorn.set_pixel(x, y+1, digit[0][1]colour[picker][0],digit[0][1]colour[picker][1], digit[0][1]colour[picker][2]) picounicorn.set_pixel(x+1, y+1, digit[1][1]colour[picker][0],digit[1][1]colour[picker][1], digit[1][1]colour[picker][2]) picounicorn.set_pixel(x+2, y+1, digit[2][1]colour[picker][0],digit[2][1]colour[picker][1], digit[2][1]colour[picker][2]) picounicorn.set_pixel(x, y+2, digit[0][2]colour[picker][0],digit[0][2]colour[picker][1], digit[0][2]colour[picker][2]) picounicorn.set_pixel(x+1, y+2, digit[1][2]colour[picker][0],digit[1][2]colour[picker][1], digit[1][2]colour[picker][2]) picounicorn.set_pixel(x+2, y+2, digit[2][2]colour[picker][0],digit[2][2]colour[picker][1], digit[2][2]colour[picker][2]) picounicorn.set_pixel(x, y+3, digit[0][3]colour[picker][0],digit[0][3]colour[picker][1], digit[0][3]colour[picker][2]) picounicorn.set_pixel(x+1, y+3, digit[1][3]colour[picker][0],digit[1][3]colour[picker][1], digit[1][3]colour[picker][2]) picounicorn.set_pixel(x+2, y+3, digit[2][3]colour[picker][0],digit[2][3]colour[picker][1], digit[2][3]colour[picker][2]) picounicorn.set_pixel(x, y+4, digit[0][4]colour[picker][0],digit[0][4]colour[picker][1], digit[0][4]colour[picker][2]) picounicorn.set_pixel(x+1, y+4, digit[1][4]colour[picker][0],digit[1][4]colour[picker][1], digit[1][4]colour[picker][2]) picounicorn.set_pixel(x+2, y+4, digit[2][4]colour[picker][0],digit[2][4]colour[picker][1], digit[2][4]*colour[picker][2]) return

Process clock characters

def character(x,y,char): if char == 10: digit(x,y,blank,0) return

if char == 0:
    digit(x,y,zero,1)
    return

if char == 1:
    digit(x,y,one,1)
    return

if char == 2:
    digit(x,y,two,1)
    return

if char == 3:
    digit(x,y,three,1)
    return

if char == 4:
    digit(x,y,four,1)
    return

if char == 5:
    digit(x,y,five,1)
    return

if char == 6:
    digit(x,y,six,1)
    return

if char == 7:
    digit(x,y,seven,1)
    return

if char == 8:
    digit(x,y,eight,1)
    return

if char == 9:
    digit(x,y,nine,1)
    return

Clear the display

def clear(): for x in range(w): for y in range(h): picounicorn.set_pixel(x, y, 0, 0, 0)

Does nothing at the moment

def butt1handler(): if picounicorn.is_pressed(picounicorn.BUTT1_A): return if picounicorn.is_pressed(picounicorn.BUTT1_B): return if picounicorn.is_pressed(picounicorn.BUTT1_X): return if picounicorn.is_pressed(picounicorn.BUTT1_Y): return

clear() # blank

First draw of clock

character(0,1,digit_a) character(4,1,digit_b) character(9,1,digit_c) character(13,1,digit_d)

Main clock loop

while 1==1:

for x in range(0,60):
    time.sleep(1)  
    seconds = seconds + 1

    if seconds == 60: 
        for x in range(0,seconds/3.75):
            picounicorn.set_pixel(x, 0, 0,0,0) 
            picounicorn.set_pixel(x, 6, 0,0,0)  
        seconds = 0

    for x in range(0,seconds/3.75):
        picounicorn.set_pixel(x, 0, 1*colour[2][0],1*colour[2][1], 1*colour[2][2])    
        picounicorn.set_pixel(x, 6, 1*colour[2][0],1*colour[2][1], 1*colour[2][2]) 

# Increment clock
digit_d = digit_d + 1  

if digit_d==10:
    digit_c=digit_c+1
    digit_d=0

    character(9,1,10) # blank

if digit_c==6:
    digit_b=digit_b+1
    digit_c=0

    character(4,1,10) # blank

if digit_b==10:
    digit_a=digit_a+1
    digit_b=0

    character(0,1,10) # blank

if digit_a==2 and digit_b==4:
    digit_d=0
    digit_c=0
    digit_b=0
    digit_a=0       

character(13,1,10) # blank

# Draw clock
character(0,1,digit_a)
character(4,1,digit_b)
character(9,1,digit_c)
character(13,1,digit_d)
Darren-Hill commented 3 years ago

With apologies for going a little off-topic, if it's useful to anyone (and also to give a little back), inspired by the code in the previous post I've put together something similar for the Scroll Pack (as that's more or less a monochrome Unicorn Pi at the moment until the modules get more love to add text inputs and scrolling).

It also uses a slightly tweaked version of the clock example code from the ScrollPhatHD for the seconds bar at the bottom.

Code is on Pastebin - https://pastebin.com/re5AHnRA

Gadgetoid commented 3 years ago

I think I've finally fixed the hardlock upon soft reset in #196 - and I've added a basic rainbow example.

Sorry it's taken a long time for me to get comfortable enough sticking a debugger on this and actually find the time to attack the hard problems! Hopefully it's less frustrating now.

Gadgetoid commented 2 years ago

I think this is resolved now (although we could always use more examples). Feel free to re-open otherwise.

@Darren-Hill consider making a pull-request so this code isn't lost to the sands of time!