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

    RGB LED strip and CY8C4146AZS

    RASO_4733996

      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.

        • 1. Re: RGB LED strip and CY8C4146AZS
          NoTa_4591161

          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

          • 2. Re: RGB LED strip and CY8C4146AZS
            RASO_4733996

            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

            • 3. Re: RGB LED strip and CY8C4146AZS
              NoriakiT_91

              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

              • 4. Re: RGB LED strip and CY8C4146AZS
                NoTa_4591161

                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

                • 5. Re: RGB LED strip and CY8C4146AZS
                  MoTa_728816

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

                  002-TeraTerm-log.JPG

                   

                  So I will not be surprised if this works.

                  but also not will I if it does not.

                   

                  moto