Wir haben nun das Zeitalter der KI erreicht, weshalb hier weniger Lösungen und mehr das Technik Tagebuch Posts kommen.
Lösungen verlinke ich Kategorisch extra auf den weiteren Seiten des Blogs
Im Wandel von Updates kommt mit der Zeit auch ein neues Windows. Und leider funktioniert nicht immer alles. Sehen wir davon ab, das VirtualBox weitgehend Kostenlos ist und deshalb nicht gewährleistet wird, dass alle Umstände funktionieren oder unterstützt werden.
Verwendet
Windows 11 (oder Windows 10)
VirtualBox
Virtualisiertes System mit Windows 2000 Professional
Problem Beschreibung
Nach einem größeren Update oder mit dem Wechsel von Windows 10 auf Windows 11, kann das Ausführen von Virtuell Box sehr langsam werden. Man kann praktisch sehen wie Pixel für Pixel das Bild aufgebaut wird.
Drücke auf die Windows Taste und gebe 'Windows-Features aktivieren oder deaktivieren' ein
Dann deinstalliert ihr die Features durch das Entfernen der gesetzten Hakens.
Hyper-V
Windows-Hypervisor-Plattform
Windows Sandbox
Anschließend Ok und das Betriebssystem neu starten.
Lösung des Problems in Windows 11
Im Grunde das gleiche. Nur halt mit runden Ecken.
An einem anderem System konnte ich feststellen, dass nicht zwingen alle Punkte aufgeführt sein müssen. Denn je nach Hardware Unterstützung werden auch nur die Optionen wieder gegeben, die auch wirklich unterstützt werden.
Eine Sache ist noch offen: Bei meinem vorigen Blogpost konnte man in den Videos sehen, dass die LEDs beim Fade-OUT nie ganz aus waren.
Benötigt werden:
Arduino
PWM Modul PCA9685
LEDs und Widerstände
Ziel
Die LEDs sollen im Fade-OUT komplett ausgehen. Asynchrone Animationsabläufe.
Ursache
Es lag daran, dass der Wert nie den Endwert von 4095 erreicht hat. Auch, wenn das High Level nur sehr kurz anliegt, reicht die Spannungsversorgung aus, um einen LED noch glimmen zu lassen.
Daher liegt die Lösung nahe, dass am Ende eines Schleifendurchgang nochmal ein Signal-Zustand festgelegt wird, mit dem genannten Endwert. Jedoch soll das für die asynchronen Vorgänge auch funktionieren. Hier nochmal das Beispiel, in denen die LEDs nicht ganz aus sind.
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
void setup() {
pwm.begin();
pwm.setPWMFreq(1600);
Wire.setClock(400000);
}
void loop() {
int stepAdd = 10;
int leds = 4;
for (uint16_t i=0; i<4096; i += stepAdd) {
for (uint8_t pwmnum=0; pwmnum < leds; pwmnum++) {
pwm.setPWM(pwmnum, 0, 4096 - i);
}
}
delay(1000);
for (uint16_t i=0; i<4096; i += stepAdd) {
for (uint8_t pwmnum=0; pwmnum < leds; pwmnum++) {
pwm.setPWM(pwmnum, 0, i);
}
}
delay(2000);
}
Einfache Lösung
Mit der bekannten Schrittweite kann nach dem Schleifendurchlauf bedingt die PWM Ports auf den Max Wert eingestellt werden.
Das gleiche kann auch für den asynchronen Vorgang verwendet werden. Jedoch hat die bisherige Lösung einen Nachteil: Dass sie schnell unübersichtlich wird.
Die Beispiele habe ich oft nur mit zwei LEDs abgebildet, aber für 16 LEDs wird's schlecht leserlich.
Deshalb gehe ich hier mit der Beispiellösung einen Schritt weiter und lege ein Objekt an, in dem ich für die einzelne LED den Zustand hinterlegen kann.
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
unsigned long mCurrentMillis = 0;
void setup() {
pwm.begin();
pwm.setPWMFreq(1600);
Wire.setClock(400000);
// schaltet alle aus
for (uint8_t pwmnum=0; pwmnum < 16; pwmnum++) {
pwm.setPWM(pwmnum, 0, 4095);
}
}
// status objekt für eine LED
typedef struct {
unsigned long LastMillis; // letzte Zeitstand
unsigned long DistanceFromNowToLast;// Intervall länge
uint16_t Value; // aktuell verwendeter Wert
bool IsFlashing; // soll nur an und aus
bool IsGoingOn; // Schritt soll heller
// oder an sein
} ledStateType;
// Konfiguration einzelner LEDs
ledStateType mLEDs[] = {
{ 0, 5, 0, false, true }, // fade animation
{ 0, 1000, 0, true, true } // flashing
};
void PrepareLED(int ledIndex) {
int stepAdd = 10;
unsigned long rest = mCurrentMillis - mLEDs[ledIndex].LastMillis;
if(rest < mLEDs[ledIndex].DistanceFromNowToLast) {
return;
}
if(mLEDs[ledIndex].IsFlashing) {
if(mLEDs[ledIndex].IsGoingOn) {
mLEDs[ledIndex].Value = 4095;
mLEDs[ledIndex].IsGoingOn = false;
}
else {
mLEDs[ledIndex].Value = 0;
mLEDs[ledIndex].IsGoingOn = true;
}
}
else {
if(mLEDs[ledIndex].IsGoingOn) {
if(mLEDs[ledIndex].Value > stepAdd) {
mLEDs[ledIndex].Value -= stepAdd;
}
else {
mLEDs[ledIndex].Value = 0;
mLEDs[ledIndex].IsGoingOn = false;
}
}
else {
if(mLEDs[ledIndex].Value < 4096) {
mLEDs[ledIndex].Value += stepAdd;
}
if(mLEDs[ledIndex].Value > 4095 - stepAdd) {
mLEDs[ledIndex].Value = 4095;
mLEDs[ledIndex].IsGoingOn = true;
}
}
}
mLEDs[ledIndex].LastMillis = mCurrentMillis;
}
void loop() {
mCurrentMillis = millis();
for(int i = 0; i < 2; i++) {
PrepareLED(i);
pwm.setPWM(i, 0, mLEDs[i].Value);
}
}
Natürlich ist das nur eine Möglichkeit, wie der Programmablauf aussehen könnte. Der geübte C++ Programmierer würde das sicherlich anders lösen können.