Светодиод Multi Dimming - выяснение, какой светодиод доступен для затемнения

TL;DR: я попытался создать случайный узор для нескольких светодиодов, и это привело к мерцанию.

Отредактировано после ответа @chrisl.

Я создаю простую лампу, которая показывает световые узоры, используя 6 светодиодов и Arduino Uno. Цель состоит в том, чтобы в зависимости от некоторых входных данных и некоторой рандомизации шаблоны менялись. Например, только 2 индикатора одновременно, но случайным образом затухают и затухают все 6 светодиодов. Или 4 индикатора, которые случайным образом загораются и гаснут на 6 светодиодах.

Я решил создать структуру, которая будет световым узором, названным частицей, и у этой частицы есть переменная с именем led_position, которая показывает, какой светодиод включен в определенный момент. Частица может изменить свое положение, чтобы зажечь другой светодиод.

Я знаю, что это не самое ясное объяснение, но я надеюсь, что мой код будет более простым:

Основной код #include "MyTypes.h"

int led1 = 9;    // контакт ШИМ, к которому подключен светодиод
int led2 = 10; 
int led3 = 11; 
int led4 = 6; 
int led5 = 3; 
int led6 = 5; 



//целый светодиод;
int brightness;
int fadeAmount;


// Определение различных частиц
particle_type particle[]={
  { 0,led1,0, 2,   false },  
  { 1,led2,50, 2,   false },  
  { 2,led3,100,  2,   false },  
  { 3,led4,80,  2,   false },
  { 4,led5,30,  2,   false},
  { 5, led6,70,  2,   false},
};

led_type led[]={
  { 3,false },  
  { 5,false },  
  { 6,false },  
  { 9,false },
  { 10,false },
  { 11,false },
};



//инициирование частиц

void initiate_particle(particle_type& particle_example,led_type led[]){



 //берем случайный светодиод из списка светодиодов
  int number=random(5);
  led[number];
  if (led[number].busy == false){ //если светодиод не занят
    particle_example.led_position=led[number].led_position;
    led[number].busy = true ;//возьмем этот светодиод в качестве вывода
    } 

  else{
//article_example.led_position=particle_example.led_position; // оставить тот же светодиод
  }

  particle_example.reset = false; //сброс отключен
 // задержка(30);

}

void update_light(particle_type& particle_example,led_type led[]){ //обновление яркости светодиода


  analogWrite(particle_example.led_position, particle_example.brightness);  //обновляем яркость светодиода
  if (particle_example.brightness >=  160) {
    particle_example.fadeAmount = -particle_example.fadeAmount;

  }

  if (particle_example.brightness <=  160 && particle_example.brightness >=  100 ) {
    particle_example.brightness = particle_example.brightness + 2*particle_example.fadeAmount;

  }

  if (particle_example.brightness >= 50 && particle_example.brightness <=  100){ 
      particle_example.brightness = particle_example.brightness + particle_example.fadeAmount;

  }

  if (particle_example.brightness >= 0 && particle_example.brightness <=  50){ 
      particle_example.brightness = particle_example.brightness + 0.5*particle_example.fadeAmount;

  }

  if (particle_example.brightness <= 0){
    particle_example.reset= true;
    int number = particle_example.led_position;
    led[number].busy=false;
    particle_example.fadeAmount = -particle_example.fadeAmount;
  }

}

void activate_particle(particle_type& particle_example,led_type led[]){ //функция для сохранения активности светодиода

  if (particle_example.reset==true){ //если светодиод не инициирован или закончил свое затемнение
    initiate_particle(particle_example, led); // инициируем его снова
  ;}

  else {
   update_light(particle_example,led); //обновляем его яркость
  }
}

void setup() { //создаем светодиодные выходы

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  Serial.begin(9600); // серийный номер для отладки

}



void loop() {

  activate_particle(particle[0],led);
//activate_particle(particle[1],led);

//activate_particle(particle[2],led);
//activate_particle(particle[3],led);
//activate_particle(particle[4],led);
//activate_particle(particle[5],led);
//

 delay(5); // 20-17-15-12-10-7-2

}

Mytypes.h

typedef struct {
    int id;
    int led_position;
    int brightness;
    int fadeAmount;
    bool reset;
} particle_type;

typedef struct {
    int led_position;
    bool busy;
} led_type;

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

Я борюсь с этим. Я пытался добавить поле данных для занятости и создать новую структуру для светодиода, но безрезультатно.

Даже когда горит только одна частица, кажется, что другие светодиоды отключаются после нескольких раундов.

Дайте мне знать, если разберетесь, спасибо!

РЕДАКТИРОВАНИЕ 2:

    #include "MyTypes.h"

int led0 = 3;    // контакт ШИМ, к которому подключен светодиод
int led1 = 5; 
int led2 = 6; 
int led3 = 9; 
int led4 = 10; 
int led5 = 11; 



//целый светодиод;
int brightness;
int fadeAmount;


// Определение различных частиц
particle_type particle[]={
  { 0,led0,0, 4,   false },  
  { 1,led1,50, 4,   false },  
  { 2,led2,100,  4,   false },  
  { 3,led3,80,  4,   false },
  { 4,led4,30, 4,   false},
  { 5,led5,70,  4,   false},
};

led_type led[]={
  { 3,false },  
  { 5,false },  
  { 6,false },  
  { 9,false },
  { 10,false },
  { 11,false },
};



//инициирование частиц

void initiate_particle(particle_type& particle_example,led_type led[]){



 //берем случайный светодиод из списка светодиодов
  int number=random(6);
  Serial.println(number);
  led[number];
  if (led[number].busy == false){ //если светодиод не занят
    for (int i=0;i<6;i++){
      if (led[i].led_position==particle_example.led_position){
      led[i].busy=false;
      Serial.println("success");
      Serial.println(led[i].led_position);
      }
    }
    particle_example.led_position=led[number].led_position;
    Serial.println(particle_example.led_position);
    led[number].busy = true ;//возьмем этот светодиод в качестве вывода
    particle_example.reset = false; //сброс отключен
    } 

  else{
// инициировать_частицу(particle_example,led);
}


  delay(30);

}

void update_light(particle_type& particle_example,led_type led[]){ //обновление яркости светодиода
      analogWrite(particle_example.led_position, particle_example.brightness);  //обновляем яркость светодиода

  if (particle_example.brightness >=  160) {
    particle_example.fadeAmount = -particle_example.fadeAmount;
    particle_example.brightness = particle_example.brightness + 2*particle_example.fadeAmount;
  }

  else if (particle_example.brightness <  160 && particle_example.brightness >=  100 ) {
    particle_example.brightness = particle_example.brightness + 1.5*particle_example.fadeAmount;

  }

  else if (particle_example.brightness > 50 && particle_example.brightness <=  100){ 
      particle_example.brightness = particle_example.brightness + particle_example.fadeAmount;

  }

  else if (particle_example.brightness > 0 && particle_example.brightness <=  50){ 
      particle_example.brightness = particle_example.brightness + 0.25*particle_example.fadeAmount;

  }

  else if (particle_example.brightness <= 0){
    particle_example.reset= true;
    particle_example.brightness =0;
    int number = particle_example.led_position;

    if (particle_example.fadeAmount<0){
      particle_example.brightness = 0;
      particle_example.fadeAmount = -particle_example.fadeAmount;
    }
    else{
      particle_example.brightness = particle_example.brightness + 0.5*particle_example.fadeAmount;
    }

  }




}

void activate_particle(particle_type& particle_example,led_type led[]){ //функция для сохранения активности светодиода

  if (particle_example.reset==true){ //если светодиод не инициирован или закончил свое затемнение
    initiate_particle(particle_example, led); // инициируем его снова
  ;}

  else {
   update_light(particle_example,led); //обновляем его яркость
  }
}

void setup() { //создаем светодиодные выходы
  pinMode(led0, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);

  Serial.begin(9600); // серийный номер для отладки

}



void loop() {

  activate_particle(particle[0],led);
  activate_particle(particle[1],led);
  activate_particle(particle[2],led);
//activate_particle(particle[3],led);
//activate_particle(particle[4],led);
//activate_particle(particle[5],led);
//

 delay(10); // 20-17-15-12-10-7-2

}


void loop() {

  activate_particle(particle[0],led);
  activate_particle(particle[1],led);
  activate_particle(particle[2],led);
  activate_particle(particle[3],led);
//activate_particle(particle[4],led);
//activate_particle(particle[5],led);
//

 delay(10); // 20-17-15-12-10-7-2

}

Теперь код хорошо работает до 3 частиц, но для 4, 5, 6 частиц все портится с мерцанием и отсутствием света.

, 👍0


1 ответ


Лучший ответ:

0

Это кажется мне логической проблемой. Вы определяете "частицу", которая не привязана к специальному светодиоду (как частица, которая прыгает из одной позиции в другую). Затем вы включили флаг занятости, который должен предотвратить использование светодиода более чем одной частицей за раз. Но вы включили этот флаг в частицу. Занятость — это состояние светодиода, а не частицы, поэтому включение этого в частицу не даст того, что вы хотите.

Если вы хотите использовать эту логику, вам нужно создать структуру, представляющую отдельный светодиод. Полями структуры будут номер вывода и флаг занятости. Вы можете создать список светодиодов с экземплярами этой структуры. Затем, чтобы выбрать новую позицию для частицы, вам нужно проверить, установлен ли флаг занятости этой позиции. Если нет, выберите эту позицию и установите флаг занятости. Снимите флажок, когда вы удалите частицу из позиции.


После вашего редактирования я вижу больше проблем. Сначала общая проблема: в настоящее время новая частица, которая хочет изменить свою позицию, нуждается в свободной (не занятой) позиции для перемещения. У вас есть 6 позиций светодиода, поэтому с 6 частицами не будет никакого движения. Вы можете изменить это, освободив положение светодиода (установив для его флага занятости значение false), когда исчезновение частицы завершено. Тем не менее, при таком способе могут возникнуть проблемы с синхронизацией, в зависимости от общего временного поведения скетча (первая частица, освободившая позицию светодиода, не найдет другую свободную позицию и должна ждать. Это может привести к тому, что 2 частицы просто поменяются своими позициями). ).

Затем в void update_light() у вас есть несколько операторов if, которые проверяют яркость частиц. Но внутри этих утверждений вы меняете яркость. Так что возможно, что будет выполнено несколько операторов if. Вместо этого следует использовать if else if, чтобы мог выполняться только один из операторов.

А в void Initial_particle() вы проверяете, занята ли выбранная позиция светодиода. Но если позиция уже занята, вы все равно устанавливаете флаг частиц reset в false. Это означает, что activate_particles() будет обновлять яркость частиц, несмотря на то, что в настоящее время у частиц нет действительного положения светодиода. Вы не должны устанавливать reset в false, если у частиц нет правильного положения светодиода. И задержка в конце функции инициации, на мой взгляд, не играет никакой роли.

,

Привет Крисл, извините за флуд :). Спасибо за ваш ответ, теперь система работает лучше с 1-3 частицами, но все еще имеет проблемы с 4,5,6 одновременно. Дайте мне знать, если у вас есть идея., @Guillaume_slize

@Guillaume_slize Я добавил дополнительные пояснения к своему ответу, @chrisl

Привет, Крис, большое спасибо за длинное объяснение. Это проясняет ситуацию, я изменил код в соответствии с вашими советами, но теперь он ведет себя странно (небольшое свечение некоторых светодиодов). Два светодиода, которые меняются местами или остаются на одном месте, когда горят 6 источников света/частиц, — это нормально, я надеялся, что система сможет поддерживать все конфигурации от 1 до 6, но, возможно, придется кодировать еще один для 6., @Guillaume_slize

Хорошо, я исправил несколько ошибок, и теперь он работает нормально до 4. Я думаю, что 5 и 6 слишком нестабильны для такого количества светодиодов., @Guillaume_slize