RGB LED strip and CY8C4146AZS

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
RASO_4733996
Level 1
Level 1

Hello,

I want to Drive RGB LED strip using PSoC 4100S Plus family member CY8C4146.

So my questions are,

          1. How can I drive the RGB LED strip like WB2812?

          2. Is UDBs are required to drive the RGB LED strip?

Because there is no UDB in PSoC 4100S Plus.

Thanks in Advance.

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

At first this sounded an easy sample,

but this ended up my first fight in the ns range time adjustment.

For those advanced PSoC experts, this could be done by using UDB or DMA & PWM.

But unfortunately I am not that advanced.

According to the data sheet you linked the timing requirements are

000-timing-info.JPG

When I tried with CY8CKIT-149 running at 24MHz,

only rising and falling gpio using DOUT_Write()  took around 1 us.

This meant we had no margin to adjust.

So I changed the clock to 48MHz.

001-48Mhz-IMO.JPG

Now flipping GPIO took only 500ns (0.5us)

I ran a simple test

=================

#define INC_DELAY   i++

#define code_0()     DOUT_Write(1);DOUT_Write(0);INC_DELAY;

#define code_1()     DOUT_Write(1);INC_DELAY;DOUT_Write(0);

void min_test(void)

{

    volatile int i = 0 ;

//    TrigOut_Write(1) ;

    code_0() ;

    code_1() ;

    code_0() ;

    code_1() ;

//    TrigOut_Write(0) ;

}

===================

And it gave me

T0H: 480ns T0L: 760ns, T1H: 740ns , T1L: 550ns

IMG_4335.JPG

So all values were withing the required range.

Then I modified the code for 24bit loop.

But the loop made the later half of the signal (low level) much longer.

So it was a time for hacking.

I noticed that calling DOUT_Write() costs a function calling time,

so I dragged out the contents of DOUT_Write() from the generated DOUT.c

And also the "value" variable was replaced with a constant of 0 or 1.

Now DOUT_Write(1) ended up

            drVal = (uint8)(DOUT_DR & (uint8)(~DOUT_MASK));

            DOUT_DR = (drVal | ((uint8)(1 << DOUT_SHIFT) & DOUT_MASK));

After all my send_data() function looks like

====================

void send_value(uint8_t r, uint8_t g, uint8_t b)

{

    volatile int i = 0 ;

    uint8_t      int_status ;

    uint8        drVal ;

  

    uint32_t composit_value = 0 ;

    uint32_t mask ;

    mask = 0x01 << 23 ;

    composit_value = (g << 16) | (r << 😎 | b ;

  

    int_status = CyEnterCriticalSection() ;

  

    do {

        if (composit_value & mask) {

            // code_1

            // DOUT_Write(1) ;

            drVal = (uint8)(DOUT_DR & (uint8)(~DOUT_MASK));

            DOUT_DR = (drVal | ((uint8)(1 << DOUT_SHIFT) & DOUT_MASK));

            INC_DELAY ; INC_DELAY ; INC_DELAY ; INC_DELAY ;

          

            // DOUT_Write(0) ;

            drVal = (uint8)(DOUT_DR & (uint8)(~DOUT_MASK));

            DOUT_DR = (drVal | ((uint8)(0 << DOUT_SHIFT) & DOUT_MASK));

        } else {

            // code_0

            // DOUT_Write(1) ;

            drVal = (uint8)(DOUT_DR & (uint8)(~DOUT_MASK));

            DOUT_DR = (drVal | ((uint8)(1 << DOUT_SHIFT) & DOUT_MASK));

          

            INC_DELAY ; INC_DELAY ;

            // DOUT_Write(0) ;

            drVal = (uint8)(DOUT_DR & (uint8)(~DOUT_MASK));

            DOUT_DR = (drVal | ((uint8)(0 << DOUT_SHIFT) & DOUT_MASK));      

          

            INC_DELAY ; INC_DELAY ; INC_DELAY ;

        }

    } while( mask >>= 1 ) ;

  

    CyExitCriticalSection(int_status) ;

}

====================

As far as I tested with values of  0, 255, 170

the wave form seemed to be within the range.

002-TeraTerm-log.JPG

So I will not be surprised if this works.

but also not will I if it does not.

moto

View solution in original post

5 Replies
Kenshow
Level 8
Level 8
Distributor - Marubun (Japan)
50 solutions authored 25 solutions authored 10 solutions authored

Hi,

How much current do you think the LED will draw?

I think that general MCU does not have enough current to drive the LEDs like WB2812.

The current that can be applied to a single GPIO is about several mA. If you need more current, bundle some GPIO pins or add an external LED driver device. LED can be controlled programmatically without UDB.

Regards,

Kenshow

0 Likes

Thank you Kenshow for response.

The strip consist of 6 RGB LED which can be individually controlled.

For Current requirement I am using external power source.

The strip has three pins

5V

GND

Data In (single wire communication)

The Data In is used to control the LEDs

https://www.pololu.com/product/2547

0 Likes
NoriTan
Employee
Employee
25 sign-ins 5 questions asked 10 sign-ins

You can find an implementation on PSoC 4200 using UDB in following page.

https://www.element14.com/community/thread/27131/

PSoC 4 Pioneer Kit Community Project#100 – PSoC 4 Times Square LED Billboard

I don't know if this can be implemented in PSoC 4100S without UDB.

Regards,

Noriaki

0 Likes
Kenshow
Level 8
Level 8
Distributor - Marubun (Japan)
50 solutions authored 25 solutions authored 10 solutions authored

Hi,

The WB2812 can be connected sequentially, so you can control only one data line. I think that it can be achieved by setting GPIO and combining it with CyDelay(), or by using a serial interface such as SPI instead.

Regards,

Kenshow

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

At first this sounded an easy sample,

but this ended up my first fight in the ns range time adjustment.

For those advanced PSoC experts, this could be done by using UDB or DMA & PWM.

But unfortunately I am not that advanced.

According to the data sheet you linked the timing requirements are

000-timing-info.JPG

When I tried with CY8CKIT-149 running at 24MHz,

only rising and falling gpio using DOUT_Write()  took around 1 us.

This meant we had no margin to adjust.

So I changed the clock to 48MHz.

001-48Mhz-IMO.JPG

Now flipping GPIO took only 500ns (0.5us)

I ran a simple test

=================

#define INC_DELAY   i++

#define code_0()     DOUT_Write(1);DOUT_Write(0);INC_DELAY;

#define code_1()     DOUT_Write(1);INC_DELAY;DOUT_Write(0);

void min_test(void)

{

    volatile int i = 0 ;

//    TrigOut_Write(1) ;

    code_0() ;

    code_1() ;

    code_0() ;

    code_1() ;

//    TrigOut_Write(0) ;

}

===================

And it gave me

T0H: 480ns T0L: 760ns, T1H: 740ns , T1L: 550ns

IMG_4335.JPG

So all values were withing the required range.

Then I modified the code for 24bit loop.

But the loop made the later half of the signal (low level) much longer.

So it was a time for hacking.

I noticed that calling DOUT_Write() costs a function calling time,

so I dragged out the contents of DOUT_Write() from the generated DOUT.c

And also the "value" variable was replaced with a constant of 0 or 1.

Now DOUT_Write(1) ended up

            drVal = (uint8)(DOUT_DR & (uint8)(~DOUT_MASK));

            DOUT_DR = (drVal | ((uint8)(1 << DOUT_SHIFT) & DOUT_MASK));

After all my send_data() function looks like

====================

void send_value(uint8_t r, uint8_t g, uint8_t b)

{

    volatile int i = 0 ;

    uint8_t      int_status ;

    uint8        drVal ;

  

    uint32_t composit_value = 0 ;

    uint32_t mask ;

    mask = 0x01 << 23 ;

    composit_value = (g << 16) | (r << 😎 | b ;

  

    int_status = CyEnterCriticalSection() ;

  

    do {

        if (composit_value & mask) {

            // code_1

            // DOUT_Write(1) ;

            drVal = (uint8)(DOUT_DR & (uint8)(~DOUT_MASK));

            DOUT_DR = (drVal | ((uint8)(1 << DOUT_SHIFT) & DOUT_MASK));

            INC_DELAY ; INC_DELAY ; INC_DELAY ; INC_DELAY ;

          

            // DOUT_Write(0) ;

            drVal = (uint8)(DOUT_DR & (uint8)(~DOUT_MASK));

            DOUT_DR = (drVal | ((uint8)(0 << DOUT_SHIFT) & DOUT_MASK));

        } else {

            // code_0

            // DOUT_Write(1) ;

            drVal = (uint8)(DOUT_DR & (uint8)(~DOUT_MASK));

            DOUT_DR = (drVal | ((uint8)(1 << DOUT_SHIFT) & DOUT_MASK));

          

            INC_DELAY ; INC_DELAY ;

            // DOUT_Write(0) ;

            drVal = (uint8)(DOUT_DR & (uint8)(~DOUT_MASK));

            DOUT_DR = (drVal | ((uint8)(0 << DOUT_SHIFT) & DOUT_MASK));      

          

            INC_DELAY ; INC_DELAY ; INC_DELAY ;

        }

    } while( mask >>= 1 ) ;

  

    CyExitCriticalSection(int_status) ;

}

====================

As far as I tested with values of  0, 255, 170

the wave form seemed to be within the range.

002-TeraTerm-log.JPG

So I will not be surprised if this works.

but also not will I if it does not.

moto