Sonntag, 15. Mai 2022

Windows 11 und langsame VirtualBox


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.

 

Ursache

Nun im Grunde kenne ich nicht die eigentliche Technische Ursache, warum ein eingeschaltetes Feature in Windows 11 für Virtuelle Maschinen Probleme erzeugt. Vielleicht hilft diese Beschreibung, die ich in den Weiten des Internets gefunden habe. (https://www.pctipp.ch/praxis/virtualisierung/quaelend-langsame-virtualbox-unter-windows-11-2742835.html?page=1_abhilfe-hyper-v-sandbox-nbsp---weg-damit)

 

Lösung des Problems in Windows 10

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.


Montag, 9. Mai 2022

Karosseriebeleuchtung mit PCA9685 (Zusatz)

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.

 #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);  
  uint16_t iSetValue = 0;  
  for (uint16_t i=0; i < 4096; i += stepAdd) {  
   for (uint8_t pwmnum=0; pwmnum < leds; pwmnum++) {  
    pwm.setPWM(pwmnum, 0, i);  
   }  
   iSetValue = i;  
  }  
  if(iSetValue > 4095 - stepAdd) {  
   for (uint8_t pwmnum=0; pwmnum < leds; pwmnum++) {  
    pwm.setPWM(pwmnum, 0, 4095);  
   }  
  }  
  delay(2000);  
 }  

Lösung für asynchrone Vorgänge

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.



Vorheriger Blog Post:

Gehäuseentwurf für Signalleuchten (Part 1)

RGB LEDs und LIPO Akkus sind bestellt. Weil ich bereits die Abmessungen habe, kann ich schon mal mit dem Gehäuseentwurf in Blender anfangen....