arduino:silentbase_802_neopixel:programmversion_1
Neopixel-Feuereffekt für das SilentBase 802 - Programmversion 1
Diesem Programm liegt der Fire2012-Effekt von Mark Kriegsman aus der FastLED-Bibliothek zugrunde, der allerdings so umgeschrieben wurde, dass er mit der Adafruit NeoPixel-Bibliothek funktioniert.
// 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 <Adafruit_NeoPixel.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 2 // NeoPixel-Strip rechte Seite
#define NEOPIN2 4 // NeoPixel-Strip linke Seite
#define POWERPIN 3 // Schaltet über den MOSFET die NeoPixel-Streifen ein
#define LEDPIN1 6 // LED 1
#define LEDPIN2 8 // LED 2
#define ONE_WIRE_BUS 11 // Datenleitung für die Temperatursensoren DS18B20
//-------------------------- 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
int numPixels = 71; // Anzahl der NeoPixel
float temperature; // Die höchste an den drei Sensoren gemessene Temperatur
int load; // Variable repäsentiert später die Differenz zwischen minimaler und maximaler Netzteillast in Prozent
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 sparkling; // Variable für Beleuchtungseffekt Flammen
int cooldown;
static byte heat[71]; // Ein Array für die Temperaturwerte
byte t192; // Variable für Beleuchtungseffekt Flammen
// Definiert die NeoPixel-Strips
Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(numPixels, NEOPIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(numPixels, NEOPIN2, NEO_GRB + NEO_KHZ800);
// Definiert die globalen RGBW-Werte
byte r = 0;
byte g = 0;
byte b = 0;
byte w = 0;
// 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 = 5; // Delay für Effekte
int intervalSerialPrint = 1000; // Delay für serielle Ausgabe
void setup() {
digitalWrite(POWERPIN, LOW); // Schaltet den MOSFET aus
Serial.begin(115200);
// Initialisiere die NeoPixel-Pins
pinMode(NEOPIN1, OUTPUT);
pinMode(NEOPIN2, OUTPUT);
pinMode(POWERPIN, OUTPUT);
pinMode(LEDPIN1, OUTPUT);
pinMode(LEDPIN2, OUTPUT);
// Initialisiere die NeoPixel-Strips
digitalWrite(POWERPIN, HIGH);
strip1.begin(); // Initialisiert das Neopixel
//strip1.show(); // Macht das NeoPixel sichtbar
strip1.clear(); // Macht das NeoPixel aus
strip2.begin(); // Initialisiert das Neopixel
//strip2.show(); // Macht das NeoPixel sichtbar
strip2.clear(); // Macht das NeoPixel aus
// Start up the 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);
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);
delay (2000);
}
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
/*
digitalWrite(POWERPIN, HIGH); // Schaltet den MOSFET durch
strip1.begin(); // Initialisiert das Neopixel
strip1.show(); // Macht das NeoPixel sichtbar
//strip1.clear(); // Macht das NeoPixel aus
strip2.begin(); // Initialisiert das Neopixel
strip2.show(); // Macht das NeoPixel sichtbar
//strip2.clear(); // Macht das NeoPixel aus
*/
}
// 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: ");
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 = 0;
temperature = tempSensor0;
if(tempSensor1 > temperature) {
temperature = tempSensor1;
}
if(tempSensor2 > temperature) {
temperature = tempSensor2;
}
#ifdef DEBUG_SENSOR
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println(" °C");
#endif
// Berechenen der Blinkfrequenz von LED2
if(temperature < temperature_min) {
temperature = temperature_min;
}
if(temperature > temperature_max) {
temperature = temperature_max;
}
intervalLED = map(temperature, temperature_min, temperature_max, 1000, 250);
#ifdef DEBUG_SENSOR
Serial.print("Blink frequency LED2: "); Serial.println(intervalLED); Serial.print(" ms");
#endif
// Berechnung der Netzteillast in Prozent: Bei ruhendem Desktop soll der Wert 0 sein, bei maximaler Auslastung 100
load = map(temperature, temperature_min, temperature_max, 0, 100);
// 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, 20);
// Berechnung von Sparkling 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
sparkling = map(temperature, temperature_min, temperature_max, 30, 200);
#ifdef DEBUG_EFFECT
//Serial.print("load: ");
Serial.print(load); Serial.print("\t");
//Serial.print("cooling: ");
Serial.print(cooling); Serial.print("\t");
//Serial.print("sparkling: ");
Serial.println(sparkling);
#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) {
// Step 1. Cool down every cell a little
for(int i = 0; i < numPixels; i++) {
cooldown = random(0, ((cooling * 10) / numPixels) + 2);
if(cooldown > heat[i]) {
heat[i] = 0;
} else {
heat[i] = heat[i] - cooldown;
}
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
if( t192 > 0x80) { // hottest
for(int k = numPixels - 1; k >= 2; k--) {
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3; // muss noch angepasst werden
}
} else if( t192 > 0x40 ) { // middle
for(int k = numPixels - 1; k >= 2; k--) {
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3; // muss noch angepasst werden
}
} else { // coolest
for(int k = numPixels - 1; k >= 2; k--) {
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3; // muss noch angepasst werden
}
}
// Step 3. Randomly ignite new 'sparks' near the bottom
if(random(255) < sparkling) {
int l = random(7);
heat[l] = heat[l] + random(160,255);
//heat[l] = random(160,255);
}
// Step 4. Convert heat to LED colors
for(int j = numPixels -1; j >= 0; j--) {
// Scale 'heat' down from 0-255 to 0-191
t192 = round((heat[j] /255.0) * 191);
// calculate ramp up from
byte heatramp = t192 & 0x3F; // 0..63
heatramp <<= 2; // scale up to 0..252
// figure out which third of the spectrum we're in:
if( t192 > 0x80) { // hottest
strip1.setPixelColor(map(j, 0, numPixels, numPixels, 0), 255, 255, heatramp);
strip2.setPixelColor(map(j, 0, numPixels, numPixels, 0), 255, 255, heatramp);
} else if( t192 > 0x40 ) { // middle
strip1.setPixelColor(map(j, 0, numPixels, numPixels, 0), 255, heatramp, 0);
strip2.setPixelColor(map(j, 0, numPixels, numPixels, 0), 255, heatramp, 0);
} else { // coolest
strip1.setPixelColor(map(j, 0, numPixels, numPixels, 0), heatramp, 0, 0);
strip2.setPixelColor(map(j, 0, numPixels, numPixels, 0), heatramp, 0, 0);
}
}
strip1.show();
strip2.show();
//Speichere die aktuelle Zeit in die zughörige Variable
previousMillisEffect = currentMillis;
}
}
// 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();
}
arduino/silentbase_802_neopixel/programmversion_1.txt · Zuletzt geändert: 18.05.2023 12:34 von 127.0.0.1