Seeed-Studio / Grove_LED_Bar

A powerful MY9221 LED driver
MIT License
30 stars 45 forks source link

CircularLed Python Lib #31

Open Khaos66 opened 1 year ago

Khaos66 commented 1 year ago

Hi I've tryed to port the c++ code for the circular led ring for the arduino to python code for the rpi + grove-head. I think I matched the code 1:1. But sadly only one half of the ring will light up and I can't get it to work for the full ring. Can you please help me?

from __future__ import print_function
from grove.gpio import GPIO
import numpy as np
import time

class CircularLed:
    def __init__(self, dataPin, clkPin):
        self.gioClk = GPIO(clkPin, GPIO.OUT)
        self.gioData = GPIO(dataPin, GPIO.OUT)
        self._clk=0

    def setLeds(self, arr):
        print("set circle leds",arr)
        self.send16bit(0x00)
        for x in arr[0:12]:
            self.send16bit(x)
        self.send16bit(0x00)
        for x in arr[12:24]:
            self.send16bit(x)
        self.latch()

    def send16bit(self, data):
        for i in range(0,16):
            # If MSB is 1, write one and clock it, else write 0 and clock
            if (data & 0x8000) != 0:
                self.gioData.write(1)
            else:
                self.gioData.write(0)
            self.clk()

            # Advance to the next bit to send
            data <<= 1

    def latch(self):
        self.gioData.write(0)
        # for x in range(0,4):
        #     self.clk()
        time.sleep(0.00001)
        for i in range(1,9):
            self.gioData.write(i % 2)
        # time.sleep(0.00001)
        # for x in range(0,4):
        #     self.clk()

    def clk(self):
        self._clk=abs(self._clk-1)
        self.gioClk.write(self._clk)

def test():
    print("Testing CircularLed")
    circle = CircularLed(6,5)

    data = np.ones(25, dtype = 'i4')

    for i in range(0,41):
        y = data[1:25]
        circle.setLeds(y)
        x = np.ones(1, dtype = 'i4')
        if i % 8 < 4:
            x += 0x10
        data = np.concatenate((y, x))
        time.sleep(0.1)

if __name__ == "__main__":
    test()

EDIT: It looks like the second half of the data array is overriding the first half. so somehow the led ring is not moving to the second segment and instead writing both halfs to the first half of the ring. My animation stops with the data transferred via the second half of the array. See

        for x in arr[12:24]:
            self.send16bit(x)

If I comment this part out, the animation looks different and stops with the data of the first half of the array. This is how I recognized that both halfs of the data array are controlling only the first half of the led ring

Khaos66 commented 1 year ago

@ytsuboi @Pillar1989 Maybe you know of some spec sheet about the signal that the led ring uses? I couldn't find one online to research why this isn't working...

ackPeng commented 1 month ago

@Khaos66 Is this problem solved?

Khaos66 commented 1 month ago

@ackPeng Hi thanks for answering!

It is not solved. But I've got an Arduino by now and the C example code for the Arduino is working fine, as long as I don't increase the delays (or add debug logs, which delay the timing too).

So I think python on raspberry pi is too slow to meet the specs of the hardware?!