5 Replies Latest reply on Aug 4, 2020 11:00 PM by MoTa_728816

    RGB LED strip and CY8C4146AZS




      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.

        • 1. Re: RGB LED strip and CY8C4146AZS



          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.




          • 2. Re: RGB LED strip and CY8C4146AZS

            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



            Data In (single wire communication)


            The Data In is used to control the LEDs



            • 3. Re: RGB LED strip and CY8C4146AZS

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



              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.




              • 4. Re: RGB LED strip and CY8C4146AZS



                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.




                • 5. Re: RGB LED strip and CY8C4146AZS



                  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


                  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.


                  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


                  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 << 8) | 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.



                  So I will not be surprised if this works.

                  but also not will I if it does not.