This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC3220MODA: Problem in dimming fan

Part Number: CC3220MODA
Other Parts Discussed in Thread: CC3200

Hi,

I am using cc3220MODA for my application.

I have problem in dimming fan.

I use one thread for mqtt client which receive dimming value of appliance.

Fan dimming is working in cc3200 device but that same dimming code i put in cc3220 it is not working. My dimming code is active when zero crossing (ZCD) interrupt is detected.

I tried dimming in 2 case: 

CASE 1 > I put all logic of dimming in ZCD interrupt.

CASE 2 > Set one variable when ZCD interrupt detect. then one separate thread with highest priority which handle logic of dimming.

In both case there is no dimming happen. some time device power failure restart.

Thanks,

Dinkar

  • Hi Dinkar,

    I'm glad that you are working with the CC32xx devices and are evaluating the new CC3220. I'm afraid I don't have enough information about the issue to provide a suggestion of what the issue may be.

    It sounds like you are able to successfully receive the dimming value in the MQTT thread. The issue sounds like it may be around either the zero-crossing detection interrupt or adjusting the output to see the dimming effect.

    Please provide a description of how you ported your code from CC3200 to the CC3220 as well as the scheme for reading the input/setting the output.

    Best Regards,
    Ben M
  • Hi Ben,

    I am not port all code from cc3200 to cc3220. But copy and past dimming logic from cc3200 to cc3220.

    Dinkar

  • Hi Dinkar,

    Please share what the dimming logic is doing - How are you controlling the output? How are you reading the input?
    Where is the process breaking down? Can you debug and see where things seem to stop working?

    Thanks!
    Ben M
  • Hi ben,

    this is continuously check that zero_cross_cnt change  , if change then work dimming code.

    dinkar

  • Hi Dinkar,

    And as far as I understand, the issue you are seeing is that the "SetApplianceOff()" call is not causing the change you are expected. Is that correct?
    I still do not understand where the problem lies. Can you share what steps you have taken to debug this and what piece is not working?

    Thanks,
    Ben M
  • Hi Ben,

    GPIO status is change when i "setApplianceOff()" is call.

    I can not able to debug this code because of our ZCD pulse come faster at aprox. 200 pulse per second. so i can not understand which piece is not working.

    Thanks,

    Dinkar

  • Hi Dinkar,

    From your last post, my understanding is that setting the device response to the dimming (SetApplianceOff/SetApplianceOn) works fine. However, I do not understand which part you are saying is not working. Check to make sure you are correctly receiving the dimming value over MQTT. Then make sure the values are being passed to the thread handling the dimming correctly. I also recommend checking that the device is sleeping correctly for your usleep() call. You are correct to try this code outside of an interrupt handler because you will want an interrupt handler to be as short as possible.

    Best Regards,
    Ben M
  • Hi Ben,

    Thanks for reply.

    I think that usleep() is working perfectly because this is freertos function.

    How can i check that usleep() function is working perfectly because this is microsecond delay?

    Give me a suggestion.

    Dinkar

  • Hi Dinkar,

    For example, try a simplified version of your code where you bypass the dimming logic and instead just try to toggle the output on, sleep, then off. Check to see this works as expected. Then I recommend trying the same for all the pieces that make up your dimming application.

    Best Regards,
    Ben M

  • Hi Dinkar,

    I haven't heard back from you, so I'm assuming you were able to resolve your issue. If not, please post a reply here or create a new thread.

    Thanks,
    Ben M
  • Hi Ben ,

    I am try the code as you said. first i on gpio then usleep(1000000) for 1 sec then gpio off. this work as i expect. but when i try for dimming logic my Appliance is not dim.

    Dinkar
  • Hi Dinkar,

    Is the GPIO and delay supposed to create a PWM type output? If so, I would recommend moving this to an actual PWM using the new TI-Drivers in the CC3220 SDK.

    Best Regards,
    Ben M
  • Hi Ben,

    We can not use PWM output because we have triac based circuit for dimming. So we need to detect zero crossing interrupt and then on or off gpio according to our dimming value. For continues PWM it did not check weather zero croccing interrupt is arrive or not.

    Dinkar

  • Hi Dinkar,

    Then I recommend checking that the interrupt is occurring as expected and measuring the GPIO output state using a logic analyzer.

    Best Regards,
    Ben M

  • Hi Ben,

    My dimming problem is partially solve. I set hard code delay instead of usleep freertos function. Other problem is happen now is that when i set some dimming value then my device is restarted automatically

    Here is code in my attachment.

    Dinkar

    gpiointerrupt.c
    /*
     * Copyright (c) 2015-2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== gpiointerrupt.c ========
     */
    #include <stdint.h>
    #include <stddef.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    #include <ti/devices/cc32xx/inc/hw_nvic.h>
    #include <ti/devices/cc32xx/inc/hw_types.h>
    
    #include "pthread.h"
    
    int dimming_value=20;
    int zero_cross_cnt=0;
    int x,y=0;
    int a=0;
    int dim=0;
    int desend_speed[3][2] = { { 100, 1 }, { 200, 2 } };
    
    pthread_t mqttThread = (pthread_t) NULL;
    
    #define SYSTICKMS               (1000 / SYSTICKHZ)
    #define SYSTICKHZ               1000
    #define F_CPU 80000000L
    
    void delayMicroseconds(unsigned int us);
    void delay(unsigned int millis);
    
    void delayMicroseconds(unsigned int us)
    {
         // Systick timer rolls over every 1000000/SYSTICKHZ microseconds
         if (us > (1000000UL / SYSTICKHZ - 1)) {
          delay(us / 1000);  // delay milliseconds
          us = us % 1000;     // handle remainder of delay
         };
    
         // 24 bit timer - mask off undefined bits
         unsigned long startTime = HWREG(NVIC_ST_CURRENT) & NVIC_ST_CURRENT_M;
    
         unsigned long ticks = (unsigned long)us * (F_CPU/1000000UL);
         volatile unsigned long elapsedTime;
    
         if (ticks > startTime) {
          ticks = (ticks + (NVIC_ST_CURRENT_M - (unsigned long)F_CPU / SYSTICKHZ)) & NVIC_ST_CURRENT_M;
         }
    
         do {
          elapsedTime = (startTime-(HWREG(NVIC_ST_CURRENT) & NVIC_ST_CURRENT_M )) & NVIC_ST_CURRENT_M;
         } while(elapsedTime <= ticks);
    }
    
    void delay(unsigned int millis)
    {
        unsigned long i;
        for(i=0; i<millis*2; i++){
        delayMicroseconds(500);
        }
    }
    
    
    /*
     *  ======== gpioButtonFxn0 ========
     *  Callback function for the GPIO interrupt on Board_GPIO_BUTTON0.
     */
    void gpioButtonFxn0(uint_least8_t index)
    {
        /* Clear the GPIO interrupt and toggle an LED */
        GPIO_toggle(Board_GPIO_LED0);
    }
    
    
    void gpioButtonFxn1(uint_least8_t index)
    {
        if(CC3220SF_LAUNCHXL_GPIO_SW2 == index)
        {
            GPIO_clearInt(index);
            GPIO_disableInt(index);
    
            zero_cross_cnt++;
    
            GPIO_enableInt(index);
        }
    }
    
    
    void *Thread_ZCD_Handler(void *pvParameters)
    {
        int temp_zero_cross_cnt=0;
        int max_dim=0;
        int max_app=8;
    
        GPIO_write(Board_LED2, Board_LED_OFF);
        task_sleep(5);
        GPIO_write(Board_LED2, Board_LED_ON);
        while(1)
        {
            usleep(10);
            while(temp_zero_cross_cnt == zero_cross_cnt)
            {
                usleep(50);
    //            usleep(100);
            }
    //        temp_zero_cross_cnt = zero_cross_cnt;
    
            x=0;
            max_dim=0;
            max_app=8;
            if(dimming_value == 0)
            {
                //gpio off
    //            GPIO_write(Board_LED0, Board_LED_OFF);
                GPIO_write(Board_LED1, Board_LED_OFF);
            }
            else if (dimming_value == 100)
            {
                //gpio on
    //            GPIO_write(Board_LED0, Board_LED_ON);
                GPIO_write(Board_LED1, Board_LED_ON);
            }
            else
            {
                x++;
                if(x>2) //max 2 dimmable device
                {continue;}
                desend_speed[x][0] = dimming_value;
                desend_speed[x][1] = 1;
            }
    
            max_dim=x;
    
            desend_speed[0][0] = 100;
            for (x = 1; x < (max_dim + 1); x++)
            {
    
                    if (desend_speed[x][0] != 0)
                    {
                        a = ((desend_speed[x - 1][0] - desend_speed[x][0]) * 55);   //40);   //50);     //max 2500us so multiply by 25
                        if (a > 0)
                        {
                            if(dim)
                            {
    //                            usleep(a);
                                delayMicroseconds(a);
                            }
                        }
    
                          if(dim){
                              //gpio on
    //                          GPIO_write(Board_LED0, Board_LED_ON);
                              GPIO_write(Board_LED1, Board_LED_ON);
                          }
                          else{
                              //gpio off
    //                          GPIO_write(Board_LED0, Board_LED_OFF);
                              GPIO_write(Board_LED1, Board_LED_OFF);
                          }
    
                    }
            }
    
            if(dim)
            {
                delayMicroseconds(100);
            }
            if(dimming_value < 100)
            {
                //gpio off
    //            GPIO_write(Board_LED0, Board_LED_OFF);
                GPIO_write(Board_LED1, Board_LED_OFF);
            }
    
            if(dim){
                 dim=0;
             }
             else{
                 dim=1;
             }
            dim =1;
            temp_zero_cross_cnt = zero_cross_cnt;
    
        }
    
    }
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        pthread_attr_t pAttrs;
        struct sched_param priParam;
        int32_t retc = 0;
    
        /* Call driver init functions */
        GPIO_init();
    
        /* Turn on user LED */
        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
    
        /* install Button callback */
        GPIO_setCallback(Board_GPIO_BUTTON0, gpioButtonFxn1);
    
        /* Enable interrupts */
        GPIO_enableInt(Board_GPIO_BUTTON0);
    
        pthread_attr_init(&pAttrs);
        priParam.sched_priority = 5;
        retc = pthread_attr_setschedparam(&pAttrs, &priParam);
        retc |= pthread_attr_setstacksize(&pAttrs, 1000);
        retc |= pthread_attr_setdetachstate(&pAttrs, PTHREAD_CREATE_DETACHED);
    
        retc = pthread_create(&mqttThread, &pAttrs, Thread_ZCD_Handler, (void *) NULL);
        if (retc != 0)
        {
    //        UART_PRINT("scheduler thread create fail\n\r");
    //        return;
        }
    
        return (NULL);
    }
    

  • Hi Dinkar,

    dinkar patel said:
    when i set some dimming value

    By this, do you mean when you set dimming_value = 20?

    dinkar patel said:
    then my device is restarted automatically

    How are you seeing that the device is restarting?

    It appears that your loop is just designed to run whenever you press the button. Is that correct?

    Are you working with an EVM or with a custom board?

    If it is an EVM you may want to implement a de-bounce mechanism for the button in SW.

    Best Regards,

    Ben M

  • Hi Ben,

    My dimming_value is 20 in this case.

    I see that whenever device restart then Board_LED2 is ON after 5 seconds. so i can see that  device is restart.

    My loop is run whenever ZCD interrupt not on button press. On Board_GPIO_BUTTON0 pin there is connection for ZCD interrupt.

    I am using my custom board. My ZCD interrupt pin is pulled up externally.

    Dinkar 

  • Hi Dinkar,

    Yes, the button press appears to take the handler out of the loop where the system sleeps at the beginning of the handler while(1). I recommend checking that the power supply to the device on your board is stable if you suspect the system is resetting itself since there is nothing in the application that appears to be causing a hibernate/reset cycle. Please also check the reset line of the device to make sure it is not being toggled to help identify the reset cause.

    Best Regards,
    Ben M