Nouvelles:

25/06/2023 : Mise à jour du forum. En cas de bug, merci de contacter le Grand Sachem

Menu principal

Animation simulation du feu

Démarré par Attiny, 26 Mai 2021 à 19:07:46

« précédent - suivant »

0 Membres et 1 Invité sur ce sujet

Attiny

Bonjour

L'article de Ph Blondé "Simulation de l'effet néon pour un bâtiment" est une très bonne présentation des LEDS adressables WS2812 (ou NeoPixel chez Adafruit).
Je les utilise depuis peu sous la forme d'un module 8 LEDs (version similaire à celle de Philippe) et également sous forme de LED individuelle 5 mm. https://www.gotronic.fr/art-5-leds-rgb-5mm-neopixel-ada1938-22883.html
Sur un autre forum un membre souhaitait une simulation d'incendie.
Par le plus pur des hasards je suis tombé sur un article traitant de ce sujet et utilisant ce type de LEDs.
Je pense qu'il pourrait en intéresser certains.

Le montage utilise:
- un Attiny85 ou un Uno ou un Nano
- un potentiomètre de 10K pour le réglage du clignotement du feu
- un module 8 LEDS  https://www.vs-elec.fr/fr/leds/2051-module-ruban-de-led-ws2812-5050-rvb-pour-arduino-3665662013330.html
- une alimentation 5V (consommation moyenne 60mA)


Le code:

/*attiny simu feu neopixel2
  ATtiny85 - NeoPixel Fire With Potentiometer
  v. 1.0
  Copyright (C) 2018 Robert Ulbricht
  https://www.arduinoslovakia.eu

  IDE: 1.8.5 or higher
  Board: ATtiny85
  Core: https://github.com/SpenceKonde/ATTinyCore

  Libraries
  NeoPixel: https://github.com/adafruit/Adafruit_NeoPixel

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.

            Brochage ATTINY85

                 1| U  |8  +5V
            pot  2|    |7  DIN module
                 3|    |6
            GND  4|    |5
  //
*/
#include <Adafruit_NeoPixel.h>

#define PIN 2 // pin connectée à la broche DIN du module
#define CNT 8 // nombre de leds sur le module
#define RANDOM_MAX 160 // bornage max de l'aléatoire

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(CNT, PIN, NEO_GRB + NEO_KHZ800);

uint32_t fire_color   = strip.Color ( 80,  35,  00);//
uint32_t off_color    = strip.Color (  0,  0,  0);

///
/// Fire simulator
///
class NeoFire
{
    Adafruit_NeoPixel &strip;
  public:
    NeoFire(Adafruit_NeoPixel&);
    void Draw();
    void Clear();
    void AddColor(uint8_t position, uint32_t color);
    void SubstractColor(uint8_t position, uint32_t color);
    uint32_t Blend(uint32_t color1, uint32_t color2);
    uint32_t Substract(uint32_t color1, uint32_t color2);
};


/// Constructor
NeoFire::NeoFire(Adafruit_NeoPixel& n_strip)
  : strip (n_strip)
{
}


/// Set all colors
void NeoFire::Draw()
{
  Clear();

  int pot = analogRead(A3);
  pot = map(pot, 0, 1023, 0, RANDOM_MAX);

  for (int i = 0; i < CNT; i++)
  {
    AddColor(i, fire_color);
    int r = random(pot);
    uint32_t diff_color = strip.Color (r, r / 2, r / 2);
    SubstractColor(i, diff_color);
  }

  strip.show();
}


/// Set color of LED
void NeoFire::AddColor(uint8_t position, uint32_t color)
{
  uint32_t blended_color = Blend(strip.getPixelColor(position), color);
  strip.setPixelColor(position, blended_color);
}

/// Set color of LED
void NeoFire::SubstractColor(uint8_t position, uint32_t color)
{
  uint32_t blended_color = Substract(strip.getPixelColor(position), color);
  strip.setPixelColor(position, blended_color);
}

/// Color blending
uint32_t NeoFire::Blend(uint32_t color1, uint32_t color2)
{
  uint8_t r1, g1, b1;
  uint8_t r2, g2, b2;
  uint8_t r3, g3, b3;

  r1 = (uint8_t)(color1 >> 16),
  g1 = (uint8_t)(color1 >>  8),
  b1 = (uint8_t)(color1 >>  0);

  r2 = (uint8_t)(color2 >> 16),
  g2 = (uint8_t)(color2 >>  8),
  b2 = (uint8_t)(color2 >>  0);

  return strip.Color(constrain(r1 + r2, 0, 255), constrain(g1 + g2, 0, 255), constrain(b1 + b2, 0, 255));
}

/// Color blending
uint32_t NeoFire::Substract(uint32_t color1, uint32_t color2)
{
  uint8_t r1, g1, b1;
  uint8_t r2, g2, b2;
  uint8_t r3, g3, b3;
  int16_t r, g, b;

  r1 = (uint8_t)(color1 >> 16),
  g1 = (uint8_t)(color1 >>  8),
  b1 = (uint8_t)(color1 >>  0);

  r2 = (uint8_t)(color2 >> 16),
  g2 = (uint8_t)(color2 >>  8),
  b2 = (uint8_t)(color2 >>  0);

  r = (int16_t)r1 - (int16_t)r2;
  g = (int16_t)g1 - (int16_t)g2;
  b = (int16_t)b1 - (int16_t)b2;
  if (r < 0) r = 0;
  if (g < 0) g = 0;
  if (b < 0) b = 0;

  return strip.Color(r, g, b);
}

/// Every LED to black
void NeoFire::Clear()
{
  for (uint16_t i = 0; i < strip.numPixels (); i++)
    strip.setPixelColor(i, off_color);
}

NeoFire fire(strip);

/// Setup
void setup()
{
  strip.begin();
  strip.show(); // toutes les leds sont éteintes'
}

/// Main loop
void loop()
{
  fire.Draw();
  delay(random(50, 150));
}


Remarques
-Le code tourne sans aucun problème sur un Uno ou un Nano. L'ATtiny85 est un choix personnel considérant le nombre d'E/S nécessaires.
-J'ai essayé le montage en utilisant toutes les 8 Leds du montage mais déjà avec simplement 3 l'effet est intéressant.
Dans ce cas au lieu: #define CNT 8  écrire: #define CNT 3

Sans oublier la platine d'essai. Amusez vous bien :)

Ph Blondé

Bonjour et merci pour cette réalisation.
C'est vrai que c'est un thème souvent abordé et nombreuses sont les demandes.
Comme il me reste une barrette de 8 Leds, je vais faire ; cela servira certainement à quelqu'un  :)

Citation de: Attiny le 26 Mai 2021 à 19:07:46
-J'ai essayé le montage en utilisant toutes les 8 Leds du montage mais déjà avec simplement 3 l'effet est intéressant.
Oui, d'accord avec toi, il faut chercher le "simple" ; l'effet résultant est d'autant plus évident.

Encore merci  :D :D :D :D
Philippe Blondé
Un 59 dans le 22

Attiny

Bonjour Philippe

Si tu essayes ce montage pourrais tu éventuellement faire une petite vidéo montrant le résultat? (hélas moi je ne sais pas le faire  :(
Si tu as l'occasion essayes aussi avec les LEDS Neopixel individuelles 5mm https://www.gotronic.fr/art-5-leds-rgb-5mm-neopixel-ada1938-22883.htm#complte_desc
En cliquant sur ce lien tu trouveras le brochage de ces composants. L'alimentation se fait sous 5V et il vaut mieux brancher un petit condo de 100nF en parallèle sur les pattes +5V et GND.
Dans le programme selon la documentation Adafruit, il faut juste apporter la modification suivante:
   -au lieu de: Adafruit_NeoPixel strip = Adafruit_NeoPixel(CNT, PIN, NEO_GRB + NEO_KHZ800);
   -écrire: Adafruit_NeoPixel strip = Adafruit_NeoPixel(CNT, PIN, NEO_RGB + NEO_KHZ800);

Dans un avenir plus ou moins proche je vais essayer les rubans de leds WS2812. Ce que j'envisage c'est un éclairage personnalisé pour animer un bâtiment (une couleur différente pour chaque pièce).
J'ai déjà testé le concept au moyen du module 8 leds. Pour l'animation je me suis basé et modifié un code existant publié sur le site Locoduino. Si certains sont intéressés je créerais un nouveau sujet sur ce thème.
Bonne continuation


Attiny

Dans mon précédent message je parlais de leds Neopixel individuelles et des modifications nécessaires dans le code.
J'ai réécris ce dernier et refais le schéma pour une meilleure compréhension.

Tout d'abord le code:
/*attiny simu feu neopixel3
   utilisation de leds neopixel individuelles
   Copyright (C) 2018 Robert Ulbricht
  https://www.arduinoslovakia.eu

  Libraries
  NeoPixel: https://github.com/adafruit/Adafruit_NeoPixel

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.

            Brochage ATTINY85

                 1| U  |8    +5V
          pot A3 2|    |7 2  DIN de la 1ère led
                 3|    |6
            GND  4|    |5

*/
#include <Adafruit_NeoPixel.h>

#define PIN 2 // pin connectée à la broche DIN du module
#define CNT 3 // nombre de leds connectées en série
#define RANDOM_MAX 160 // bornage max de l'aléatoire

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(CNT, PIN, NEO_RGB + NEO_KHZ800);

uint32_t fire_color   = strip.Color ( 80,  35,  00);//
uint32_t off_color    = strip.Color (  0,  0,  0);

///
/// Fire simulator
///
class NeoFire
{
    Adafruit_NeoPixel &strip;
  public:
    NeoFire(Adafruit_NeoPixel&);
    void Draw();
    void Clear();
    void AddColor(uint8_t position, uint32_t color);
    void SubstractColor(uint8_t position, uint32_t color);
    uint32_t Blend(uint32_t color1, uint32_t color2);
    uint32_t Substract(uint32_t color1, uint32_t color2);
};


/// Constructor
NeoFire::NeoFire(Adafruit_NeoPixel& n_strip)
  : strip (n_strip)
{
}


/// Set all colors
void NeoFire::Draw()
{
  Clear();

  int pot = analogRead(A3);
  pot = map(pot, 0, 1023, 0, RANDOM_MAX);

  for (int i = 0; i < CNT; i++)
  {
    AddColor(i, fire_color);
    int r = random(pot);
    uint32_t diff_color = strip.Color (r, r / 2, r / 2);
    SubstractColor(i, diff_color);
  }

  strip.show();
}


/// Set color of LED
void NeoFire::AddColor(uint8_t position, uint32_t color)
{
  uint32_t blended_color = Blend(strip.getPixelColor(position), color);
  strip.setPixelColor(position, blended_color);
}

/// Set color of LED
void NeoFire::SubstractColor(uint8_t position, uint32_t color)
{
  uint32_t blended_color = Substract(strip.getPixelColor(position), color);
  strip.setPixelColor(position, blended_color);
}

/// Color blending
uint32_t NeoFire::Blend(uint32_t color1, uint32_t color2)
{
  uint8_t r1, g1, b1;
  uint8_t r2, g2, b2;
  uint8_t r3, g3, b3;

  r1 = (uint8_t)(color1 >> 16),
  g1 = (uint8_t)(color1 >>  8),
  b1 = (uint8_t)(color1 >>  0);

  r2 = (uint8_t)(color2 >> 16),
  g2 = (uint8_t)(color2 >>  8),
  b2 = (uint8_t)(color2 >>  0);

  return strip.Color(constrain(r1 + r2, 0, 255), constrain(g1 + g2, 0, 255), constrain(b1 + b2, 0, 255));
}

/// Color blending
uint32_t NeoFire::Substract(uint32_t color1, uint32_t color2)
{
  uint8_t r1, g1, b1;
  uint8_t r2, g2, b2;
  uint8_t r3, g3, b3;
  int16_t r, g, b;

  r1 = (uint8_t)(color1 >> 16),
  g1 = (uint8_t)(color1 >>  8),
  b1 = (uint8_t)(color1 >>  0);

  r2 = (uint8_t)(color2 >> 16),
  g2 = (uint8_t)(color2 >>  8),
  b2 = (uint8_t)(color2 >>  0);

  r = (int16_t)r1 - (int16_t)r2;
  g = (int16_t)g1 - (int16_t)g2;
  b = (int16_t)b1 - (int16_t)b2;
  if (r < 0) r = 0;
  if (g < 0) g = 0;
  if (b < 0) b = 0;

  return strip.Color(r, g, b);
}

/// Every LED to black
void NeoFire::Clear()
{
  for (uint16_t i = 0; i < strip.numPixels (); i++)
    strip.setPixelColor(i, off_color);
}

NeoFire fire(strip);

/// Setup
void setup()
{
  strip.begin();
  strip.show(); // toutes les leds sont éteintes
}

/// Main loop
void loop()
{
  fire.Draw();
  delay(random(50, 150));
}



et la nouvelle plaine d'essai

Attiny

Cela a été difficile pour moi mais avec l'aide d'un ami, nous avons réalisé deux petites vidéos avec le module 8 leds.

Le rendu des couleurs n'est pas parfait, en réalité les couleurs sont plus dans l' orange.
Au moins vous aurez un aperçu des effets obtenus en jouant sur le potentiomètre.





Bon visionnage