Search code examples
cstm32rgbnucleo

RGB Color mixing using nucleo development board


My party_sequence function (at case 9: is constantly running (as intended) but when i try to turn the LEDs off using my button switch, the function still runs.

How do I get the function to stop running when I turn the switch off and go back to case:0 when I turn the switch back on?

I am using a simple button switch to switch through the colors.

I am new to programming so if there is more information you need please let me know.

Thank you!

party_sequence function:

  void party_sequence(void) {
      int i = 0;

      while (1) {
          for (i = 0; i < 360; i++) {
              __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, sins[i]); // Red
              __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, sins[(i + 120) % 360]); // Green
              __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, sins[(i + 240) % 360]); // Blue

              HAL_Delay(2);
          }
      }
  };

Full Code:

int main(void)
{

  HAL_Init();

  SystemClock_Config();


  MX_GPIO_Init();
  MX_TIM3_Init();

  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); // Red
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // Green
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4); // Blue

    uint8_t sins[360] = {
        127,129,131,134,136,138,140,143,145,147,149,151,154,156,158,160,162,164,166,169,171,173,175,177,179,181,183,185,187,189,191,193,195,196,198,200,
        202,204,205,207,209,211,212,214,216,217,219,220,222,223,225,226,227,229,230,231,233,234,235,236,237,239,240,241,242,243,243,244,245,246,247,248,
        248,249,250,250,251,251,252,252,253,253,253,254,254,254,254,254,254,254,255,254,254,254,254,254,254,254,253,253,253,252,252,251,251,250,250,249,
        248,248,247,246,245,244,243,243,242,241,240,239,237,236,235,234,233,231,230,229,227,226,225,223,222,220,219,217,216,214,212,211,209,207,205,204,
        202,200,198,196,195,193,191,189,187,185,183,181,179,177,175,173,171,169,166,164,162,160,158,156,154,151,149,147,145,143,140,138,136,134,131,129,
        127,125,123,120,118,116,114,111,109,107,105,103,100,98,96,94,92,90,88,85,83,81,79,77,75,73,71,69,67,65,63,61,59,58,56,54,
        52,50,49,47,45,43,42,40,38,37,35,34,32,31,29,28,27,25,24,23,21,20,19,18,17,15,14,13,12,11,11,10,9,8,7,6,
        6,5,4,4,3,3,2,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,3,3,4,4,5,
        6,6,7,8,9,10,11,11,12,13,14,15,17,18,19,20,21,23,24,25,27,28,29,31,32,34,35,37,38,40,42,43,45,47,49,50,
        52,54,56,58,59,61,63,65,67,69,71,73,75,77,79,81,83,85,88,90,92,94,96,98,100,103,105,107,109,111,114,116,118,120,123,125
    };

  enum button_state_e {
      BUTTON_NOT_PRESSED,
      BUTTON_JUST_PRESSED,
      BUTTON_PRESSED
  };

  static enum button_state_e button_state = BUTTON_NOT_PRESSED;

  static uint8_t color_sequence = 0;

  void red_sequence(void) {
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
  };

  void green_sequence(void) {
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 230); // Green
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
  };

  void blue_sequence(void) {
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 230); // Blue
  };

  void pink_sequence(void) {
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 50); // Blue
  };

  void teal_sequence(void) {
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 230); // Green
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 230); // Blue
  };

  void yellow_sequence(void) {
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 140); // Green
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue

  };

  void orange_sequence(void) {
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 25); // Green
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
  };

  void purple_sequence(void) {
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 100); // Blue
  };

  void white_sequence(void) {
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 230); // Green
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 230); // Blue
  };

  void party_sequence(void) {
      int i = 0;

      while (1) {
          for (i = 0; i < 360; i++) {
              __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, sins[i]); // Red
              __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, sins[(i + 120) % 360]); // Green
              __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, sins[(i + 240) % 360]); // Blue

              HAL_Delay(2);
          }
      }
  };

  void switch_off_all_leds(void)
  {
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
  };

  while (1)
  {

     bool pressed = (HAL_GPIO_ReadPin(Toggle_Switch_GPIO_Port, Toggle_Switch_Pin) == GPIO_PIN_SET);

        switch (button_state)
        {
            case BUTTON_NOT_PRESSED:
                if (pressed)
                    button_state = BUTTON_JUST_PRESSED;
                break;

            case BUTTON_JUST_PRESSED:
                if (pressed)
                {
                    button_state = BUTTON_PRESSED;

                    switch (color_sequence) {

                    case 0:
                        red_sequence();
                        break;
                    case 1:
                        green_sequence();
                        break;
                    case 2:
                        blue_sequence();
                        break;
                    case 3:
                        pink_sequence();
                        break;
                    case 4:
                        teal_sequence();
                        break;
                    case 5:
                        yellow_sequence();
                        break;
                    case 6:
                        orange_sequence();
                        break;
                    case 7:
                        purple_sequence();
                        break;
                    case 8:
                        white_sequence();
                        break;
                    case 9:
                        party_sequence();
                        break;
                    }

                    color_sequence = (color_sequence + 1) % 10;
                }
                else
                    button_state = BUTTON_NOT_PRESSED;
                break;

            case BUTTON_PRESSED:
                if (!pressed)
                {
                    button_state = BUTTON_NOT_PRESSED;
                    switch_off_all_leds();
                }
                break;
        }

        HAL_Delay(10);

  }
}

Solution

  • How about changing the infinite while (1) loop in party_sequence() to be this instead:

    while (HAL_GPIO_ReadPin(Toggle_Switch_GPIO_Port, Toggle_Switch_Pin) == GPIO_PIN_SET)
    {
        // Do the party sequence
    }
    

    i.e. it will run for as long as the switch is "on", but will stop when the switch goes "off". Then your main loop will see that the switch is off and turn off the LEDs.

    As an alternative, if you want it to immediately go off rather than completing the sequence, do this:

    while (1) {
        for (i = 0; i < 360; i++) {
            __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, sins[i]); // Red
            __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, sins[(i + 120) % 360]); // Green
            __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, sins[(i + 240) % 360]); // Blue
    
            HAL_Delay(2);
    
            if (HAL_GPIO_ReadPin(Toggle_Switch_GPIO_Port, Toggle_Switch_Pin) != GPIO_PIN_SET)
                return;
        }
    }