Быстрое изменение цвета в состоянии удержания

По сути, создайте код, который поможет пользователям выполнить дыхательное упражнение (вдохните в течение 4 секунд, задержитесь на 4, отпустите на 4, снова задержитесь на 4, повторите), чтобы помочь им расслабиться.

Прямо сейчас мой код работает под управлением APA102. Они проходят через 5 "дыхательных" состояний: Вдох, выдох, Выдох, выдох, Отдых.

Мои светодиоды просто гаснут и переливаются аквамариновым / зеленым цветом.

Что я хотел бы сделать, так это менять цвет при каждом BREATH_HOLD_DELAY. Я хочу, чтобы людям, выполняющим дыхательные упражнения, было легче следить за светодиодным дисплеем. Прямо сейчас трудно сказать, когда происходит "задержка дыхания", когда светодиоды работают на полную яркость. Я бы хотел, чтобы светодиоды погасли зеленым цветом, немедленно переключились на синий для 4-секундного BREATH_HOLD_DELAY, а затем немедленно переключились обратно на зеленый, чтобы погаснуть и удерживать низкую яркость в течение 4.

Я действительно теряюсь в догадках, как это сделать. Я пытался выполнить оператор "если";

если (BREATH_HOLD_DELAY)

светодиоды [i] = CHSV (HUE2, 255, яркость);

Но это просто изменило цвет всего светодиода на синий, а не только на части BREATH_HOLD_DELAY.

Вот весь мой код!

#include <Servo.h>    
 
#define DATA 11                 // Данные, подключенные к цифровому выводу 11 на Arduino                                    
#define CLOCK 13                // Часы, подключенные к цифровому контакту 13 на Arduino
#define SERVO_PIN 9              // Вывод, к которому подключен сервопривод                        
#define LED_TYPE APA102         // В этой светодиодной ленте используется чипсет APA102.                                  
#define NUM_LEDS 45             // На этой цепочке 25 светодиодов
#define HUE 65                  // Цвет светодиода
#define HUE2 10                  // Цвет светодиода
#define LOOP_DELAY 20          // в миллисекундах
#define BREATH_HOLD_DELAY 3000
#define SERVO_INITAL_POSITION 0  // определить начальное значение позиции равным 0

enum breathingStates { In, ChangingToOut, Out, ChangingToIn, Rest };

//Глобальные переменные
CRGB leds[NUM_LEDS];            // массив светодиодов, назначаемых один за другим
Servo myservo;  // создать сервообъект для управления сервоприводом

 
/*====================================================================
  setup(): will run only once
=====================================================================*/

void setup() {
  Serial.begin(115200);
  LEDS.addLeds<LED_TYPE, DATA, CLOCK, RGB>(leds, NUM_LEDS);
  FastLED.clear();
  FastLED.show();
  myservo.attach(SERVO_PIN);
  myservo.write(SERVO_INITAL_POSITION); // Начальное положение сервопривода
}


/*====================================================================
  loop(): will run indefinitely
=====================================================================*/

void loop() {
  static int8_t theta = 0;
  static breathingStates breathingState = Rest;

  switch(breathingState)
  {
      case Rest:
        Serial.println("This is the first time the loop has run");
        // Выполните какие-либо дополнительные настройки, не выполненные в функции setup здесь, но это излишне
        breathingState = In;
        break;
       
      case In:
        theta++;
        if(theta >= 90){
          breathingState = ChangingToOut;
        }
        break;

      case ChangingToOut:
        delay(BREATH_HOLD_DELAY);
        breathingState = Out;
        theta--;
        break;
     
      case Out :
        theta--;
        if(theta <= -90){
          breathingState = ChangingToIn;
        }
        break;

      case ChangingToIn:
        delay(BREATH_HOLD_DELAY);
        breathingState = In;
        theta++;
        break;

       
      default:
        Serial.println("It should never have come to this... :(");
  }

  // Теперь, когда тета установлена, мы что-то делаем с ней в этом разделе функции loop()
 
  //Serial.print("Значение theta равно: "); Serial.println(theta);

  float thetaInRadians = float(theta) / 57.295;
  double dblBrightness = sin(thetaInRadians);      // Яркость светодиода
  uint8_t brightness = (dblBrightness * 127) + 128;
  Serial.print("The value of brightness is: "); Serial.println(brightness);

  // Настройка оттенка и яркости каждого светодиода
  for (int i=0; i < NUM_LEDS; i++){
    leds[i] = CHSV(HUE + i, 255, brightness);  // Установка цвета и яркости светодиодов
    
  }
 
  //Показать следующий кадр светодиодной анимации
  FastLED.show();        


  myservo.write(theta + 180);


  delay(LOOP_DELAY);
   
} ```


Would love any help or guidance. I'm very new to coding and Arduino!

, 👍1

Обсуждение

Намеренно ли цвет светодиодов немного отличается? Или все они должны иметь одинаковый цвет в определенный момент времени?, @PMF

В идеале все одного цвета, когда светодиоды горят в течение 4 секунд на полной яркости! Я думаю, что это раздел BREATH_HOLD_DELAY, @entirelyreverse

Ваша цветовая схема кажется странной: float thetaInRadians = float (theta) / 57.295; использует угол (из цветовой схемы HSV?), А Затем преобразует его в яркость. Однако яркость является вторым параметром в HSV, который вы, по-видимому, хотите контролировать отдельно. Я бы изменил оператор switch таким образом, чтобы на каждом шаге выбирался желаемый цвет / яркость, а затем, на отдельном шаге, вы переходили к нему. Таким образом, вы можете управлять желаемым целевым цветом / яркостью независимо от того, насколько быстро меняются цвета., @PMF

можно ли поставить что-то вроде if (brightness => 255) и изменить цвет таким образом? Скажите коду, что когда он достигает полной яркости, он должен быть синим, а не зеленым?, @entirelyreverse

Конечно, это все программное обеспечение. Ты можешь делать все, что захочешь., @PMF