Benutzer-Werkzeuge

Webseiten-Werkzeuge


arduino:silentbase_802_neopixel:programmversion_3

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
arduino:silentbase_802_neopixel:programmversion_3 [18.03.2023 19:02] Frickelpietarduino:silentbase_802_neopixel:programmversion_3 [18.05.2023 12:34] (aktuell) – Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
-====== Beleuchtung für BeQuiet SilentBase 802 - Programmversion 3 ====== +====== Neopixel-Feuereffekt für das SilentBase 802 - Programmversion 3 ====== 
-[[arduino:silentbase_802_neopixel:programmversion_2|Programmversion 2]] benötigt für die Berechnung des Feuer-Effekts ca. 17 Millisekunden. Das Auslesen der [[arduino:ds18b20|Temperatursensoren]] dauert ca. 2 Millisekunden. Wenngleich diese nur einmal pro Sekunde ausgelesen werden, beschränkt das die "Framerate" des Feuer-Effekts auf ca. 50. Daher habe ich mir noch einmal die Arduino-Bibliothek "FastLED" angesehen, von der ich für die [[arduino:silentbase_neopixel|NeoPixel-Beleuchtung für das SilentBase 800]] übernommen und an die NeoPixel-Bibliothek von Adafruit angepasst hatte. Ich weiß nicht aus welchem Grund, aber die Anpassung war recht schnell erledigt. Die FastLED-Bibliothek berechnet den Feuer-Effekt für beide Strips in unter 5 Millisekunden. Damit sind Framrates bis zu 200 FPS möglich.+[[arduino:silentbase_802_neopixel:programmversion_2|Programmversion 2]] benötigt für die Berechnung des Feuer-Effekts ca. 17 Millisekunden. Das Auslesen der [[arduino:ds18b20|Temperatursensoren]] dauert ca. 2 Millisekunden. Wenngleich diese nur einmal pro Sekunde ausgelesen werden, beschränkt das die "Framerate" des Feuer-Effekts auf ca. 50. Daher habe ich mir noch einmal die Arduino-Bibliothek "FastLED" angesehen, von der ich für die [[arduino:silentbase_neopixel|NeoPixel-Beleuchtung für das SilentBase 800]] übernommen und an die NeoPixel-Bibliothek von Adafruit angepasst hatte. Ich weiß nicht aus welchem Grund, aber die Anpassung war recht schnell erledigt. Die FastLED-Bibliothek berechnet den Feuer-Effekt für beide Strips in unter 5 Millisekunden. Damit sind Framrates bis zu 200 FPS möglich. 66 FPS sehen auf jeden Fall besser aus als 50 FPS.
  
 Arbuino-Bibliothek FeasLED: https://fastled.io/ Arbuino-Bibliothek FeasLED: https://fastled.io/
 +
 +<code>
 +// Beleuchtung BeQuiet SilentBase 802
 +// Arduino Nano (Every)
 +
 +//------------------------- Eingebundene Bibliotheken ---------------------//
 +#include <OneWire.h>                            // Bibliothek für die Kommunikation über OneWire
 +#include <DallasTemperature.h>                  // Bibliothek für die digitalen Temperatursensoren DS18B20
 +#include <FastLED.h>                            // Bibliothek für die NeoPixel
 +
 +// Debug-Level
 +//#define DEBUG_EFFECT                            // Ausgabe sehr vieler Daten an die serielle Schnittstelle
 +//#define DEBUG_SENSOR                            // Ausgabe der Sensordaten und Betriebszustände an die serielle Schnittstelle
 +
 +//------------------------- Definition der Inputs und Outputs ---------------------//
 +#define NEOPIN1                               // NeoPixel-Strip rechte Seite
 +#define NEOPIN2                               // NeoPixel-Strip linke Seite
 +#define POWERPIN      3                         // Schaltet über den MOSFET die NeoPixel-Streifen ein
 +#define LEDPIN1                               // LED 1
 +#define LEDPIN2                               // LED 2
 +#define ONE_WIRE_BUS 11                         // Datenleitung für die Temperatursensoren DS18B20
 +
 +//------------------------- Definition der NeoPixel-Streifen ---------------------//
 +#define COLOR_ORDER GRB            
 +#define CHIPSET     WS2812B
 +#define NUM_LEDS    71
 +#define BRIGHTNESS  200
 +
 +//-------------------------- Definition der Auflösung der Temperatursensoren ----//
 +// 9 bit resolution: 0,5°C increments, takes 94 ms for A/D conversion
 +// 10 bit resolution: 0,25°C increments, takes 188 ms for A/D conversion
 +// 11 bit resolution: 0,125°C increments, takes 375 ms for A/D conversion
 +// 12 bit resolution: 0,0625°C increments, takes 750 ms for A/D conversion
 +#define TEMPERATURE_PRECISION 11
 +
 +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
 +OneWire oneWire(ONE_WIRE_BUS);
 +
 +// Pass our oneWire reference to Dallas Temperature.
 +DallasTemperature sensors(&oneWire);
 +
 +// arrays to hold device addresses
 +DeviceAddress sensor0, sensor1, sensor2;
 +
 +// Definiert die Variablen
 +bool gReverseDirection = true;                  // Kehrt den Effekt um, wenn wahr
 +
 +float temperature;                              // Die höchste an den drei Sensoren gemessene Temperatur
 +float temperature_min = 20;                     // Konfiguriert den unteren Grenzwert der Gehäusetemperatur
 +float temperature_max = 40;                     // Konfiguriert den oberen Grenzwert der Gehäusetemperatur
 +
 +boolean LEDstate;
 +boolean POWERstate = 0;                         // Wird "1" sobald der Loop aufgerufen wird
 +
 +int cooling;                                    // Variable für Beleuchtungseffekt Flammen
 +int sparking;                                   // Variable für Beleuchtungseffekt Flammen
 +static byte heat[71];                           // Ein Array für die Temperaturwerte
 +  
 +// Definiert die NeoPixel-Strips
 +CRGB strip[NUM_LEDS];
 +
 +// Definiert die Tracking-Variablen für die IF-Abfragen
 +unsigned long previousMillisSensors = 0;
 +unsigned long previousMillisLED = 0;
 +unsigned long previousMillisEffect = 0;
 +unsigned long previousMillisSerialPrint = 0;
 +
 +// Definiert die Intervalle für die IF-Abfragen
 +int intervalSensors = 1000;                     // Delay für Auslesen der Temperatursensoren
 +int intervalLED = 500;                          // Delay für die Ausgabe der Temperatur als Blinkfrequenz der LED2
 +int intervalEffect = 15;                        // Delay für Effekte
 +int intervalSerialPrint = 1000;                 // Delay für serielle Ausgabe
 +
 +
 +//-------------------------- Setup ------------------------------------------------------------------//
 +void setup() {
 +  digitalWrite(POWERPIN, LOW);                  // Schaltet den MOSFET aus
 +  Serial.begin(115200);
 +  
 +  // Initialisiere die Output-Pins
 +  pinMode(NEOPIN1, OUTPUT);
 +  pinMode(NEOPIN2, OUTPUT);
 +  pinMode(POWERPIN, OUTPUT);
 +  pinMode(LEDPIN1, OUTPUT);
 +  pinMode(LEDPIN2, OUTPUT);
 +  
 + 
 +  // Initialisiere die NeoPixel-Strips
 +  digitalWrite(POWERPIN, HIGH);                 // Schaltet den MOSFET ein
 +
 +  FastLED.addLeds<CHIPSET, NEOPIN1, COLOR_ORDER>(strip, NUM_LEDS).setCorrection( TypicalLEDStrip );
 +  FastLED.addLeds<CHIPSET, NEOPIN2, COLOR_ORDER>(strip, NUM_LEDS).setCorrection( TypicalLEDStrip );
 +  FastLED.setBrightness( BRIGHTNESS ); 
 +  
 +  // Start up the sensor library
 +  sensors.begin();
 +
 +  // locate devices on the bus
 +  Serial.print("Locating devices...");
 +  Serial.print("Found ");
 +  Serial.print(sensors.getDeviceCount(), DEC);
 +  Serial.println(" devices.");
 +
 +  // Search for devices on the bus and assign based on an index. Ideally,
 +  // you would do this to initially discover addresses on the bus and then
 +  // use those addresses and manually assign them (see above) once you know
 +  // the devices on your bus (and assuming they don't change).
 +  //
 +  // method 1: by index
 +  if (!sensors.getAddress(sensor0, 0)) Serial.println("Unable to find address for Device 0");
 +  if (!sensors.getAddress(sensor1, 1)) Serial.println("Unable to find address for Device 1");
 +  if (!sensors.getAddress(sensor2, 2)) Serial.println("Unable to find address for Device 2");
 +
 +  // show the addresses we found on the bus
 +  Serial.print("Device 0 Address: ");
 +  printAddress(sensor0);
 +  Serial.println();
 +
 +  Serial.print("Device 1 Address: ");
 +  printAddress(sensor1);
 +  Serial.println();
 +
 +  Serial.print("Device 2 Address: ");
 +  printAddress(sensor2);
 +  Serial.println();
 +  
 +  // set the resolution to 11 bit per device
 +  sensors.setResolution(sensor0, TEMPERATURE_PRECISION);
 +  sensors.setResolution(sensor1, TEMPERATURE_PRECISION);
 +  sensors.setResolution(sensor2, TEMPERATURE_PRECISION);
 +
 +  #ifdef DEBUG_SENSOR
 +  Serial.print("Device 0 Resolution: ");
 +  Serial.println(sensors.getResolution(sensor0), DEC);
 +
 +  Serial.print("Device 1 Resolution: ");
 +  Serial.println(sensors.getResolution(sensor1), DEC);
 +
 +  Serial.print("Device 2 Resolution: ");
 +  Serial.println(sensors.getResolution(sensor2), DEC);
 +  #endif
 +  
 +delay (2000);
 +}
 +
 +//-------------------------- Loop -------------------------------------------------------------------//
 +void loop() {
 +  // Aktuelle Zeit abfragen
 +  unsigned long currentMillis = millis();
 +
 +  // Schaltet die NeoPixel ein und initialisiert die NeoPixel
 +  if(POWERstate == 0) {
 +    POWERstate = 1;
 +    digitalWrite(LEDPIN1, HIGH);                   // Schaltet LED1 ein
 +  }
 +
 +// Auslesen der Temperatursensoren und Berechnen einiger Variablen zur Beeinflussung des Effekts
 +  if ((unsigned long)(currentMillis - previousMillisSensors) >= intervalSensors) {
 +  
 +    // Request to all devices on the bus
 +    //temperature conversion - non-blocking / async
 +    unsigned long start = micros();       
 +    sensors.setWaitForConversion(false);  // makes it async
 +    sensors.requestTemperatures();
 +    sensors.setWaitForConversion(true);
 +    unsigned long stop = micros();
 +    
 +    #ifdef DEBUG_SENSOR
 +    Serial.print("Time used for reading sensors: ");
 +    Serial.print(stop - start);
 +    Serial.println(" microseconds");
 +
 +    // print the device information
 +    printData(sensor0);
 +    printData(sensor1);
 +    printData(sensor2);
 +    #endif
 +    
 +    // Berechnen der höchsten Temperatur an den verfügbaren Sensoren
 +    float tempSensor0 = sensors.getTempC(sensor0);
 +    float tempSensor1 = sensors.getTempC(sensor1);
 +    float tempSensor2 = sensors.getTempC(sensor2);
 +    temperature = max(tempSensor0, tempSensor1);
 +    temperature = max(temperature, tempSensor2);
 +
 +    #ifdef DEBUG_SENSOR
 +    Serial.print("Highest temperature: ");
 +    Serial.print(temperature);
 +    Serial.println(" °C");
 +    #endif
 +    
 +    // Berechenen der Blinkfrequenz von LED2
 +    constrain(temperature, temperature_min, temperature_max);
 +    intervalLED = map(temperature, temperature_min, temperature_max, 500, 100);
 +    #ifdef DEBUG_SENSOR
 +    Serial.print("Blink frequency LED2: "); Serial.print(intervalLED); Serial.println(" ms");
 +    #endif
 +    
 +    // Berechnung von Cooling für den Effekt Fire 2012: Legt fest, wie stark die aufsteigenden Flammen abkühlen
 +    // Werte zwischen 20 und 100 sollen am hübschesten sein, ein guter Standard ist 50
 +    cooling = map(temperature, temperature_min, temperature_max, 100, 40);
 +
 +    // Berechnung von Sparking für den Effekt Fire2012: Legt fest, wie oft ein Funke auflohdert
 +    //Werte zwischen 50 und 200 sollen am hübschesten sein, ein guter Standard ist 120
 +    sparking = map(temperature, temperature_min, temperature_max, 30, 100);
 +
 +    #ifdef DEBUG_SENSOR
 +    //Serial.print("cooling: ");
 +    Serial.print(cooling); Serial.print("\t");
 +    //Serial.print("sparkling: ");
 +    Serial.println(sparking);
 +    #endif
 +    
 +  //Speichere die aktuelle Zeit in die zughörige Variable
 +  previousMillisSensors = currentMillis;
 +  }
 +
 +
 +// Ausgabe der Temperatur als Blinkfrequenz der LED1
 +  if ((unsigned long)(currentMillis - previousMillisLED) >= intervalLED) {
 +
 +    if(LEDstate == 0) {
 +      digitalWrite(LEDPIN2, HIGH);
 +      //Serial.println("LED an");
 +      LEDstate = 1;
 +    }
 +    else if(LEDstate == 1) {
 +      digitalWrite(LEDPIN2, LOW);
 +      //Serial.println("LED aus");
 +      LEDstate = 0;
 +    }
 +    
 +    
 +  //Speichere die aktuelle Zeit in die zughörige Variable
 +  previousMillisLED = currentMillis;
 +  }
 +
 +  // Feuer-Effekt
 +  if ((unsigned long)(currentMillis - previousMillisEffect) >= intervalEffect) {
 +
 +    #ifdef DEBUG_EFFECT
 +    unsigned long start = micros();                                     // Zeitstempel Start
 +    #endif
 +    
 +    // Add entropy to random number generator; we use a lot of it.
 +    random16_add_entropy( random());
 +  
 +    // Step 1.  Cool down every cell a little
 +    for( int i = 0; i < NUM_LEDS; i++) {
 +      heat[i] = qsub8( heat[i],  random8(0, ((cooling * 10) / NUM_LEDS) + 2));
 +    }
 +  
 +    // Step 2.  Heat from each cell drifts 'up' and diffuses a little
 +    for( int k= NUM_LEDS - 1; k >= 2; k--) {
 +      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
 +    }
 +    
 +    // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
 +    if( random8() < sparking ) {
 +      int y = random8(7);
 +      heat[y] = qadd8( heat[y], random8(160,255) );
 +    }
 +
 +    // Step 4.  Map from heat cells to LED colors
 +    for( int j = 0; j < NUM_LEDS; j++) {
 +      CRGB color = HeatColor( heat[j]);
 +      int pixelnumber;
 +      if( gReverseDirection ) {
 +        pixelnumber = (NUM_LEDS-1) - j;
 +      } else {
 +        pixelnumber = j;
 +      }
 +      strip[pixelnumber] = color;
 +      //strip2[pixelnumber] = color;
 +    }
 +    FastLED.show(); // display this frame
 +  
 +    #ifdef DEBUG_EFFECT
 +    unsigned long stop = micros();                                    // Zeitstempel Stopp
 +    // Ausgabe der Zeit in Microsekunden, die für die Berechnung des Effekts benötigt wird
 +    //Serial.print("Time used for calculating effect: ");
 +    Serial.println(stop - start);
 +    //Serial.println(" microseconds");
 +    #endif
 +    
 +  //Speichere die aktuelle Zeit in die zughörige Variable
 +  previousMillisEffect = currentMillis;
 +  }
 +}
 +
 +//-------------------------- Funktionen --------------------------------------//
 +// function to print a device address
 +void printAddress(DeviceAddress deviceAddress)
 +{
 +  for (uint8_t i = 0; i < 8; i++)
 +  {
 +    // zero pad the address if necessary
 +    if (deviceAddress[i] < 16) Serial.print("0");
 +    Serial.print(deviceAddress[i], HEX);
 +  }
 +}
 +
 +// function to print the temperature for a device
 +void printTemperature(DeviceAddress deviceAddress)
 +{
 +  float tempC = sensors.getTempC(deviceAddress);
 +  Serial.print("Temp C: ");
 +  Serial.print(tempC);
 +}
 +
 +// function to print a device's resolution
 +void printResolution(DeviceAddress deviceAddress)
 +{
 +  Serial.print("Resolution: ");
 +  Serial.print(sensors.getResolution(deviceAddress));
 +  Serial.println();
 +}
 +
 +// main function to print information about a device
 +void printData(DeviceAddress deviceAddress)
 +{
 +  Serial.print("Device Address: ");
 +  printAddress(deviceAddress);
 +  Serial.print(" ");
 +  printTemperature(deviceAddress);
 +  Serial.println();
 +}
 +</code>
 +{{tag>Arduino Neopixel PC}}
arduino/silentbase_802_neopixel/programmversion_3.1679162569.txt.gz · Zuletzt geändert: 18.05.2023 12:16 (Externe Bearbeitung)