Zwischendurch möchte ich meine Raspberry Pi’s mit einer HDD verbinden. Ich habe davon noch ein paar herumliegen. Eine gute Anleitung dazu habe ich hier gefunden: https://www.youtube.com/watch?v=5S7VL8tb-fc

Weitere Links zum Thema:

Meine Verssuche das CYD mit Micropython zu betreiben.

Meine ersten Versuche waren noch nicht sehr erfolgreich. Letztendlich war es mir gelungen Das Display zum Leben zu erwecken. Allerdings wurden die Farben als BGR dargestellt, was ich nicht ändern konnte.

Schließlich konnte ich das CYD nicht mehr mit Thonny erreichen und habe Micropython neu installiert. Damit waren dann aber auch alle meine bisherigen Versuche und Änderungen gelöscht.

Nun also ein neuer Anlauf.

Zuerst erstelle ich mal eine Gliederung, das hilft mir strukturierter vorzugehen und bietet die Möglichkeit meiner Ergebnisse gleich an der richtigen Stelle zu dokumentieren – bevor ich wieder MPY neu aufspiele.

Das CYD, Daten, Eigenschaften und Varianten

Micropythonspezifische Informationen zum CYD

Hier meine aktuelle Linksammlung zum Thema:

CYD Links:

Das Display

Ich möchte zuerst das Display benutzen können. Es handelt sich dabei um einen Controller ILI9341.

Hier sind die Pinbelegungen des CYD dargestellt. Für das Display ist dort folgendes aufgeführt:

disp = ili9XXX.ili9341(factor=32, double_buffer=False, clk=14, cs=15, dc=2, rst=12, power=23, backlight=21, miso=12, mosi=13,width=320, height=240, backlight_on=1, rot=ili9XXX.LANDSCAPE)

Da dort ein anderer Treiber verwendet wird sind noch weitere Parameter enthalten, die bei dem von mir verwendeten Treiber nicht vorhanden sind.

Ich habe zuerst den ili9341.py Treiber von hier ausprobiert. Ich habe ihn nach /lib auf dem ESP32 kopiert und dann mit dem Demoprogramm demo_fonts8x8_bgcolor.py getestet.

In der Initialisierungssequenz habe ich die Zeile

self.write_cmd(self.INVON)        # Ergänzt

hinzugefügt, da ich von meinen ersten Versuchen noch wusste, das das etwas gebracht hat. Es hat sich aber gezeigt, dass die Invertierung falsch war. Siehe weiter unten.

Aber auch damit erschien kein Bild. Deshalb habe ich die Anschlüsse in demo_fonts8x8_bgcolor.py überprüft. Die waren falsch. Hier die Richtigen.

In ili9341.py ist eine falsche Geometrie als Default eingetellt. Deshalb muss hier noch width und hight angegeben werden.

spi = SPI(1, baudrate=40000000, sck=Pin(14), mosi=Pin(13))
display = Display(spi, dc=Pin(2), cs=Pin(15), rst=Pin(12), width=320, height=240)

Auch das zeigte kein Bild. Es fiel mir aber auf, das die Hintergrundbeleuchtung des Displays nicht leuchtete. Deshalb habe ich Pin21 manuell eingeschaltet:

bl = machine.Pin(21, machine.Pin.OUT)
bl.on()

Und siehe da, das Display wurde hell und test() zeigte etwas an!

Nun habe ich die folgenden Zeilen in der REPL eingegeben:

spi = SPI(1, baudrate=40000000, sck=Pin(14), mosi=Pin(13))
display = Display(spi, dc=Pin(2), cs=Pin(15), rst=Pin(12), width=320, height=240)
display.draw_text8x8(100, 120, "sollte Grün sein!", color565(0, 255, 0))

Der Text wurde angezeigt, aber in Lila. Außerdem enthält der Default 8×8 Font kein ü, es wird wohl der aus dem MPY Framebuffer sein.

Da Lila die Komplementärfarbe zu Grün ist war wohl die Invertierung falsch. Nachdem ich diese Zeile auskommentiert hatte wurde der Text auch Grün angezeigt.

Display ON/OFF

In der __init__ Methode von Display in ili9341.py steht in Zeile 171:

self.write_cmd(self.DISPLAY_ON)

Ich hatte angenommen, dass damit das Display eingeschaltet wird. Das passiert auch, aber die Hintergrundbeleuchtung hat damit nichts zu tun! Diese muß extra eingeschaltet werden:

bl = Pin(21, Pin.OUT)
bl.on()

Statt on/off kann man auch einen PWM-Anschluss darauf legen und so die Helligkeit einstellen.

Soweit ist also die grundsätzliche Funktion des Displays hergestellt.

CYDR.py

CYDR.py fasst die Möglichkeiten der Platine in einem Objekt zusammen. Das vereinfacht den Start gewaltig. Jetzt werde ich dieses Modul mal ausprobieren.

Ich habe die Datei cydr.py mit Thonny gestartet (entspricht einem Import). Dann das unten dargestellte Protokoll habe ich anschließend durchgeführt. Die getesteten Methoden habe alle funktioniert!

MicroPython v1.23.0 on 2024-06-02; Generic ESP32 module with ESP32

Type "help()" for more information.

>>> %Run -c $EDITOR_CONTENT

MPY: soft reboot
Booting...
>>> %Run -c $EDITOR_CONTENT

MPY: soft reboot
Booting...
>>> cyd = CYD(rgb_pmw=False, speaker_gain=512, display_width=320, display_height=240, wifi_ssid = None, wifi_password = None)
CYD ready...
>>> cyd.display.draw_text8x8(100, 120, "sollte Grün sein!", color565(0, 255, 0))
>>> cyd.touches()
(0, 0)
>>> cyd.touches()
(245, 113)
>>> cyd.touches()
(236, 279)
>>> cyd.play_tone(1000, 100, gain=0)
>>> cyd.play_tone(1000, 100, gain=0)
>>> cyd.wifi_connect('ssid', 'password')
connecting to network...
network config: 192.168.3.180
>>> 
  • cyd = CYD(rgb_pmw=False, speaker_gain=512, display_width=240, display_height=320, wifi_ssid = None, wifi_password = None)
    • Initialize CYD class
    • OK
  • cyd.display.ili9341_cydr_function_name()
    • Use to access ili9341_cydr functions.
    • OK
  • cyd._touch_handler(x, y)
    • Called when a touch occurs.
    • INTERNAL USE ONLY
  • cyd.touches()
    • GETS the last touch coordinates.
    • OK
  • cyd.double_tap(x, y, error_margin = 5)
    • Check for double taps.
    • ?
  • cyd.rgb(color)
    • SETS rgb LED color.
    • OK
  • cyd._remap(value, in_min, in_max, out_min, out_max)
    • Converts a value form one scale to another.
    • INTERNAL USE ONLY
  • cyd.light()
    • GETS the current light sensor value.
    • liefert nur 0.0 zurück.
  • cyd.button_boot()
    • GETS the current boot button value.
    • gibt <bound_method> zurück.
  • cyd.backlight(value)
    • SETS backlight brightness.
    • Es geht nur 1 und 0.
  • cyd.play_tone(freq, duration, gain=0)
    • Plays a tone for a given duration.
    • OK
  • cyd.mount_sd()
    • Mounts SD card
    • OK
  • cyd.unmount_sd()
    • Unmounts SD card.
    • Failed to unmount SD card
      • Laufwerk sd lässt sich nicht unmounten.
  • cyd.wifi_connect(ssid, password)
    • Connects to a WLAN network.
    • OK
  • cyd.wifi_isconnected()
    • Checks to see that the wifi connection is connected.
    • OK
  • cyd.wifi_ip()
    • Get the CYD’s IPv4 address on your WLAN.
    • OK
  • cyd.wifi_create_ap(_ssid)
    • Creates an Access Point (AP) WLAN network.
    • ?
  • cyd.shutdown()
    • Safely shutdown CYD device
      • Failed to unmount SD card
      • display off
      • ========== Goodbye ==========
      • Micropython steht in der REPL weiterhin zur Verfügung.

TODO

  • Backlight ein- und ausschalten in backlight_on() und backlight_off() integrieren.

Ich probiere gerade mit der UIFlow-IDE ein kleines Programm zu erstellen, das mittels ESP-Now eine Verbindung herstellt und Daten austauscht.

Mein erster Versuch (Master):

  • Zuerst wird ESP-Now initialisiert.
  • Dann wird ein Name (SSID) für die Arbeitsgruppe festgelegt.
  • Und schließlich die eigene MAC-Adresse geholt und angezeigt.
  • In der folgenden Schleife wird nach einem Mitglied der Arbeitsgruppe gesucht und dessen MAC angezeigt.
  • Das Mitglied wird dann in eine Liste eingetragen.
  • Die MainLoop ist noch nicht getestet.

Das Programm auf dem Slave:

  • Auch hier wird zuerst ESP-Now initialisiert.
  • Dann wird der Arbeitsgruppennamen (SSID) festgelegt und bekanntgemacht.
  • Schließlich wird die eigene MAC-Adresse geholt und angezeigt.

Mehr macht dieses Programm nicht. Das genügt aber, um vom Master erkannt zu werden!

Eine zuverlässige Datenübertragung hat aber nicht funktioniert.

Ein zweiter Anlauf

Also das Beispiel von MStack hat nicht funktioniert. Ich habe heute einen neuen Anlauf gemacht. Es funktionierte wieder nichts. Also habe ich einen ESP32 genommen und die Micropython Demo als Grundlage genommen. Das funktionierte in Thonny:

# ESPNow_test_001.py
#


import network
import espnow

sta = network.WLAN(network.STA_IF)  # Or network.AP_IF
sta.active(True)

e = espnow.ESPNow()
e.active(True)

peer = b'\x94\xb9\x7e\x8d\x41\xdc'
e.add_peer(peer)

Dieses kleine Programm hat einen ESP-Now Sender erzeugt. Mit

>>> e.send(peer, "Starting...")
True

habe ich senden können. Das Programm RX_001.m5f hat diese Aussendungen empfangen. Es waren noch kleine Fehler drinn, deshalb hier die endgültige Fassung:

Wenn eine Message empfangen wird, so wird die MAC des Senders und die Nachricht für 1 Sekunde angezeigt, dann erscheinen wieder —.

Dann habe ich am Senderprogramm gearbeitet. Das automatische Suchen von Peers habe ich rausgeschmissen und die MAC des Peers (Empfänger) ins Programm geschrieben. Damit funktionierte dann auch der Sender. Hier das Programm TX_003.m5f:

Damit ist die Grundlage für eine einseitige Verbindung mittels ESP-Now geschaffen.

Das automatische finden des Peer hat prinzipiell funktioniert. Allerdings wurde eine Slave-MAC angezeigt, die um 1 höher war, als die vom Slave selbst angezeigte.

Nachgedanken

Es ist möglich, dass der Erste Versuch unbefriedigend verlief, weil ich den Kanal auf 0 eingestellt hatte. Kanal 0 bedeutet, das der eingestellte Kanal verwendet wird. Wenn sich aus irgendwelchen Gründen bei Sender und Empfänger unterschiedliche Kanäle einstellen finden sie sich nicht.

Das werde ich vielleicht später mal testen. Für eine vorgesehenen Reichweitentest ist das jetzt ausreichend.

Kürzlich bin ich auf ein Projekt gestoßen, das mittels Adafruit_TinyUSB-Library mit einem Raspberry Pi Pico Tastatureingaben simuliert hat. Hier werde ich mir die Technik dafür erarbeiten. Deshalb befindet sich diese Seite z.Z. noch im Entstehungsmodus.

Die Entwicklungsbasis ist das Pico Restouch LCD 3,5″ Display von Waveshare. Bestückt mit einen Pico, der im Lieferumfang von azdelivery.de enthalten war. Außerdem gibt dazu einen Projektvorschlag für einen Tastatursimulator. Als IDE kommt die Arduino-IDE zum Einsatz.

Die Adafruit_TinyUSB Library stellt verschiedene HID’s (Human Interface Device) zur Verfügung. Mich interessiert hier nur die Keyboard HID. Ein Beispiel für deren Anwendung befindet sich hier. Ich habe aus diesem Beispiel nur die Teile heraus gesucht, die für das Keyboard-HID erforderlich sind:

Zuerst muss die Headerdatei eingebunden werden.

#include "Adafruit_TinyUSB.h"

Dann wird das Keyboard eingerichtet:

// -------- USB HID KEYBOARD -----------
enum { RID_KEYBOARD = 1 };
uint8_t const desc_hid_report[] = { TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(RID_KEYBOARD)) };
uint8_t keycode[6] = { HID_KEY_NONE, HID_KEY_NONE, HID_KEY_NONE, HID_KEY_NONE, HID_KEY_NONE, HID_KEY_NONE };
Adafruit_USBD_HID usb_hid;

keycode[] ist ein Array in dem der zu übertragende Text aufbereitet und an usb_hid übergeben wird. Dafür stehen Konstanten in hid.h zur Verfügung.

Ob keycode[] nur 6 Elemente enthalten darf werde ich später noch klären.

Die Anwendung ist dann ganz einfach:

keycode[0] = HID_KEY_C;
usb_hid.keyboardReport(RID_KEYBOARD, KEYBOARD_MODIFIER_LEFTCTRL, keycode);
delay(10);
usb_hid.keyboardRelease(RID_KEYBOARD);
  • In keycode[] werden die Werte eingetragen.
  • Der KEYBOARD_MODIFIER ist normalerweise 0.
  • Mit usb_hid.keyboardReport() werden die Daten zum PC geschickt.
  • Dann wird kurz gewartet (wahrscheinlich hier 10mS).
  • Und schließlich mit usb_hid.keyboardRelease() dem PC mitgeteilt, dass die Übertragung beendet ist.

Die Übertragung ist sehr zeitkritisch! Zwei gleiche Zeichen direkt hintereinander (Hallo) funktioniert meistens nicht. Hier das Ergebnis zur zuverlässigen Übertragung von „Hallo\n“:

// ----- btn_12 action
void btn_12_pressAction(void) {
  if (btn_12.justPressed()) {
    keycode[0] = HID_KEY_H;
    keycode[1] = HID_KEY_NONE;
    keycode[2] = HID_KEY_NONE;
    keycode[3] = HID_KEY_NONE;
    keycode[4] = HID_KEY_NONE;
    keycode[5] = HID_KEY_NONE;
    usb_hid.keyboardReport(RID_KEYBOARD, KEYBOARD_MODIFIER_LEFTSHIFT, keycode);
    delay(10);
    usb_hid.keyboardRelease(RID_KEYBOARD);
    delay(25);
    keycode[0] = HID_KEY_A;
    keycode[1] = HID_KEY_L;
    keycode[2] = HID_KEY_NONE;
    keycode[3] = HID_KEY_NONE;
    keycode[4] = HID_KEY_NONE;
    keycode[5] = HID_KEY_NONE;
    usb_hid.keyboardReport(RID_KEYBOARD, 0, keycode);
    delay(10);
    usb_hid.keyboardRelease(RID_KEYBOARD);
    delay(25);
    keycode[0] = HID_KEY_L;
    keycode[1] = HID_KEY_O;
    keycode[2] = HID_KEY_NONE;
    keycode[3] = HID_KEY_NONE;
    keycode[4] = HID_KEY_NONE;
    keycode[5] = HID_KEY_NONE;
    usb_hid.keyboardReport(RID_KEYBOARD, 0, keycode);
    delay(10);
    usb_hid.keyboardRelease(RID_KEYBOARD);
    delay(25);
    keycode[0] = HID_KEY_ENTER;
    keycode[1] = HID_KEY_ENTER;
    keycode[2] = HID_KEY_NONE;
    keycode[3] = HID_KEY_NONE;
    keycode[4] = HID_KEY_NONE;
    keycode[5] = HID_KEY_NONE;
    usb_hid.keyboardReport(RID_KEYBOARD, 0, keycode);
    delay(10);
    usb_hid.keyboardRelease(RID_KEYBOARD);
    btn_12.drawSmoothButton(true);
  }
}
void btn_12_releaseAction(void) {
  if (btn_12.justReleased()) {
    usb_hid.keyboardRelease(RID_KEYBOARD);
    btn_12.drawSmoothButton(false);
  }
}

Sonderbarer Weise wird Enter nur zuverlässig übergeben, wenn es zweimal gesendet wird! Es kommt zu keiner doppelten Erkennung! Es funktioniert auch, wenn Enter im ersten und im letzten Element übergeben werden.

Mysterium

Wenn schon vorher Text eingegeben wurde wird meistens 2x \n ausgegeben?!

Mit dieser Zeile in Python/Micropython lässt sich ein Verzeichnisinhalt so aufbereiten, dass es von ESP32 als Webseite ausgeliefert werden kann:

>>> import os
>>> verzeichnis_liste = ' Bytes</br>'.join([' - '.join([x[0], str(x[3])]) for x in os.ilistdir()])
>>> verzeichnis_liste
'apps - 0 Bytes</br>blocks - 0 Bytes</br>boot.py - 77 Bytes</br>emojiImg - 0 Bytes</br>img - 0 Bytes</br>main.py - 169 Bytes</br>res - 0 Bytes</br>temp.py - 85 Bytes</br>test.py - 0 Bytes</br>update - 0'
>>> 

Allerdings fügt .join() am Ende kein Trennungsstring mehr ein. Dieser muss dann noch hinzugegügt werden:

>>> verzeichnis_liste = ' Bytes</br>'.join([' - '.join([x[0], str(x[3])]) for x in os.ilistdir()]) + ' Bytes</br>'
>>> verzeichnis_liste
'apps - 0 Bytes</br>blocks - 0 Bytes</br>boot.py - 77 Bytes</br>emojiImg - 0 Bytes</br>img - 0 Bytes</br>main.py - 169 Bytes</br>res - 0 Bytes</br>temp.py - 85 Bytes</br>test.py - 0 Bytes</br>update - 0 Bytes</br>'

Nun ist es so wie es sein soll und kann in das HTML-Gerüst eingefügt werden.


Diese Seite ist noch nicht für die Öffentlichkeit nutzbar, da alles noch in der Entwicklung ist.


Die Umgebung erstellen.

Als Erstes müssen diese Dateien im Dateisystem des Gerätes erezugt werden. Dazu dient das Micropython Script mk_json.py. Dieses wird am Besten auf das Gerät kopiert. Dann im Editorfenster von Thonny geöffnet und die erforderlichen Daten eingetragen. Von Thonny aus wird es dann auf dem Gerät ausgeführt und erzeugt so die erforderlichen Dateien.

mk_json.py kann auch aus dem PC heraus ausgeführt werden. Dann besteht aber die Gefahr, dass falsche / alte Daten auf des Gerät gelangen, wenn man mit dem Script verschiedene Geräte vorbereitet.

Die erforderlichen Dateien:

Der OTA Updater benötigt einige Informationen, die ihm in verschiedenen Dateien bereitgestellt werden.

Diese Dateien sind meist im Json-Format gespeichert und haben dann die Endung .json.

Die erforderlichen Dateien sind:

Weiterlesen »

Die Installationsroutine von Thonny lässt es nicht zu, 2 Versionen von Thonny auf einem Rechner zu installieren. Wenn schon ein Thonny-Verzeichnis, ggf. auch mit anderem Namen existiert wird immer dorthin installiert und die alte Version gelöscht.


Nun gibt es derzeit das Problem, dass die M5Stack Geräte nicht mit der Version 4 von Thonny zusammenarbeiten. Es gibt wohl ein Problem mit der Größe der übertragenen Blöcke. Das kann man durch einen Eintrag in einer Config-Datei umgehen – allerdings nur bis zum nächsten Neustart des M5Stack Gerätes. Deshalb hätte ich gerne die Versionen 4.x.x und 3.3.13 auf meinem Rechner.


Ich habe die neue Version (hier 4.0.2) auf dem Rechner installiert in einem Verzeichnis Thonny_4. Dann habe ich ein weiteres Verzeichnis mit dem Namen Thonny_3 angelegt. Dahinein habe ich das Zip-file der Portabelversion 3.3.13 entpackt.

Das funktioniert.

Die Übersetzungen auf dieser Seite wurden mit DeepL.com vorgenommen und ggf. von mir korrigiert.

Es gibt verschiedene Stellen im Internet bei denen man Micropython für das Lilygo T-Device S3 finden kann. Zuerst beim „Original“ Micropython.org. Hier gibt es 3 Versionen für den S3

https://micropython.org/download/GENERIC_S3/

https://micropython.org/download/GENERIC_S3_SPIRAM_OCT/

https://micropython.org/download/GENERIC_S3_SPIRAM/

Dann gibt es noch eine Version mit integriertem ST7789 Modul:

https://github.com/russhughes/st7789s3_mpy

Zu guter Letzt noch eine Version auf die LILYGO verweist. Diese muss aber noch selbst kompiliert werden.

https://github.com/Xinyuan-LilyGO/lilygo-micropython

Zu beachten ist, dass die Startadresse beim ESP32-S3 0 ist. Beim ESP32 ist sie ansonsten 0x1000. Dieser Wert steht auch in vielen Anleitungen. Mir hat das mindestens einen Tag Probiererei gekostet, bis ich dahinter gekommen bin.

LILYGO T-Display Layout

Quelle: https://github.com/Xinyuan-LilyGO/T-Display-S3 Hier gibt es auch das Schaltbild.


Die Grafikbefehle – wird gerade bearbeitet!

Weiterlesen »

Ich brauche eine Elektronische Last mit der ich ein altes PC-Netzteil testen möchte. Von einem früherem Projekt habe ich noch einen großen Kühlkörper mit 18 x IFR540 darauf. Das Teil möchte ich als Basis nehmen.

Weitwinkel und Vorsatzlinse vertragen sich nicht so gut.

Vorüberlegungen

Umladezeit der MOS-FET-Gates

Um die Umladeströme der MOES-FET-Gatekapazitäten einzuschätzen habe ich ein bischen mit Thonny in Micropython auf einem ESP23 herumgespielt. Die folgeneden Berechnungen sind nicht exakt. Sie geben nur einen Überblick über die zu erwartenden Ströme:

>>> # Q = C*U
>>> # Q = I*t
>>> # c*u = i*t
>>> # i = (c*u)/t
>>> c = 2E-9     # max. Eingangskapazität des IRF540  [F]
>>> u = 12       # durchschnittliche Spannung am Gate [V]
>>> t = 1E-3     # Schaltzeit hier 1 ms               [s]
>>> (c*u)/t
2.4e-05          # 24 µA
>>> t = 1E-6     # Schaltzeit hier 1 µs
>>> (c*u)/t
0.024            # 24 mA
>>> 12/0.024
500.0            # Widerstand bei 12 V und 24 mA = 500 Ohm
>>> 500 * 2E-9
1e-06            # Zeitkonstante 2nF und 500 Ohm zur Kontrolle
>>> (7*c*u)/t    # Es sollen später 7x IRF540 parallel angesteuert werden
0.168            # 168 mA
>>> 

Um später eine Lastumschaltzeit in der Größenordnung 1 µs zu bekommen muss an dem Gate jedes MOS-FET mindestens 24 mA fließen können.

Bei der ursprünglichen Planung habe ich die Transistoren BD649/650 vorgesehen. Inzwischen bin ich auf das komplementäre MOS-FET-Pärchen IRF7507 gestoßen, die hier geeigneter sein könnten.

1. Versuch

Zuerst möchte ich mit nur einem MOS-FET anfangen und diesen als Last testen. Er soll einen Source-Widerstand von 0,1 Ohm / 0,5 Watt / 1% erhalten. Dieser kann maximal 2,2 Ampere vertragen. Das ist ein guter Ausgangspunkt.

Belastbarkeit der 0,1 Ohm Widerstände:

  • 0,5 Watt, 2,2 Ampere, 0,22 Volt
  • 10 Watt, 10 Ampere, 1 Volt

Für die Gesamtstrommessung befinden sich auf dem Kühlkörper auch noch 2 Messwiderstände 0,1 Ohm / 10 Watt / 0,5%. Damit lassen sich maximal 10 Ampere pro Widerstand messen, also gesamt 20 Ampere.

Die Transistoren bekommen später jeder einen 0,1 Ohm Widerstand in die Sourceleitung zum Ausgleich von Toleranzen. Somit kann jeder Transistor maximal 2,2 A fließen lassen.

Der 10 Watt Messwiderstand dient als Stromfühler. Er stellt den IST-Wert bereit. Bei 2,2 Ampere sind das 220 mV. Es macht wohl Sinn, diese Spannung zu verstärken, bevor sie mit der Referenzspannung verglichen wird.

Schaltwandler sind universelle Spannungversorgungseinheiten, die sich immer größerer Beliebtheit erfreuen und in den meisten Fällen den analogen Reglern vorgezogen werden, da sie wesentlich effektiver arbeiten. Leider erfolgt die Einstellung der Ausgangsspannung bisher immer noch analog mittels Potentiometer/Trimmer. Das ist ein Problem, wenn man die Ausgangsspannung mittels Microcontroller einstellen möchte. Ich habe mir drei Lösungsmöglichkeiten für dieses Problem angesehen:

  • Umschaltbare Widerstände
  • PWM
  • DAC mit externem Komparator

Hinweise zur Simulation

Ich habe die Simulationen mit dem kostenlosen LTspice XVII erstellt. Als Grundlage habe ich das Beispiel 1938.asc eingesetzt. Das habe ich ausgewählt, weil die Simulation damit relativ problemlos funktionierte. Es ist nur ein Beispiel und hat nichts mit dem später eingesetzten IC’s zu tun. Auch der Operationsverstärker OP07 ist nur ein Beispiel. Später werde ich eher den LM358 oder LM324 einsetzen. Diese sind aber bei LTspice nicht dabei.

Die Simulationen sind nur ein erster Versuch mit der Materie vertraut zu werden. Die wirklichen Ergebnisse werde ich später bei echten Aufbauten erhalten.

Die Bilder und Plots aus LTspice sind auf der Website nur sehr schlecht zu erkennen. Ein Linksklick mit der Mouse ins Bild zeigt es in voller Größe und dann ist auch alles gut zu erkennen.

Zum Nachvollziehen werde ich die Dateien am Ende der Kapitel anhängen, so dass Ihr sie herunterladen könnt.

Die Originalschaltung

In der Standardschaltung wird aus R1 und R2 ein Sapnnungsteiler gebildet der die Ausgangsspannung bestimmt.

Standardschaltung aus dem Beispielfile 1938.asc

Hier die Standardbeschaltung mit Impulslast.
Der Plot der Standardbeschaltung mit Impulslast.

Umschaltbare Widerstände

Noch nicht bearbeitet.

PWM

Noch nicht bearbeitet.

DAC mit externem Komparator

Die Schaltwandler IC’s besitzen einen eingebauten Komparator, der die mittels Spannungsteiler heruntergeteilte Ausgangsspannung mit einer internen Referenzspannung vergleicht und so den Schalttransistor ansteuert. Wenn eine externe Referenz möglich wäre, könnte man darüber die Ausgangsspannung mittels DAC einstellen. Da diese Möglichkeit nicht besteht, muss ein externer Komparator eingesetzt werden. Der besteht im einfachsten Fall aus einem Operationsverstärker. Der -Eingang wird mit dem DAC verbunden, der +Eingang mit der Ausgangsspannung und der Ausgang mit dem Feedback-Eingang (FB) des IC’s.

Schaltbild der Simulation in LTspice

Im obigen Schaltbild befindet sich der Operationsverstärker in der Bildmitte (OP07). V2 entspricht dem DAC. Rechts habe ich mi I1 eine Impulsstromsenke hinzugefügt. So wird der Strom zwischen 200 mA und 1,7A hin und her geschaltet. Das habe ich eingefügt, weil mich das Regelverhalten der veränderten Schaltung interessiert.

Das Ergebnis der Simulation für 3,3 Volt ausgangsspannung ist im folgenden Plot dargestellt:

Ergebnis der Simulation

Die blaue Line zeigt die Ausgangsspannung, die rote Linie den Ausgangsstrom und die grüne Linie die Spannung am FB-Eingang des IC’s. Die Reaktion der Ausgangsspannung auf die Laständerung ist dieser Darstellung kaum wahrnehmbar.

Plot mit besserer Auflösung der Ausgangsspannung.

Auch bei besserer Auflösung geht der Einfluß der Stromänderung in den systembedingten Spannungsschwankungen unter. Nur im Einschaltmoment bricht die Spannung kurz auf 3,0 Volt ein.

Allerdings ist deutlich angestiegener Rippel zu erkennen. Das dürfte an der Slew Rate von 0.3 V/μs des OP07 liegen. Für LM358/324 ist der selbe Wert im Datenblatt zu finden.

Ich habe die Simulation mit 5 Volt wiederholt. Auch dabei zeigte sich, dass die Pannung im Einschaltmoment für einen kurzen Zeitraum unter die -5%-Grenze (4,75 Volt) von 5 Volt absinkt.

Plot bei 5 Volt

Hier sind es 4,63 Volt. Nun interessiert mich, ob der 100R Widerstand in der FB-Zuleitung einen Einfluß hat:

Nun habe ich den Widerstand 0R gemacht. Da das bei LTspice nicht geht habe ich den Wert auf 0,000001R gesetzt. Damit ergibt sich tatsächlich eine kleine Veränderung. Der Wert liegt jetzt bei 4,69 Volt. 60 mV machen den Kohl nicht wirklich fett.

Dieser Spannungseinbruch dauert ca. 50 µS.

Wahrscheinlich lässt sich dieser Spannungseinbruch durch einen Stützkondensator direkt an der Last reduzieren.

Zusammenfassung und Ausblick

Grundsätzlich funktioniert dieses Konzept. Als Operationsverstärker kommen aber nur sehr schnelle Typen in Frage. Bei der Simulation wurden die Eigenschaften des IC’s durch den Operationsverstärker deutlich verschlechtert.

Simulation mit schnellem OP

ADA4891 mit 190 V/µs

Sonderbarerweise zeigte der erste Plot völlig absurde Linienzüge. Die 3,3 Volt wurden nicht erreicht. Schließlich konnte ich durch verlängern der Beobachtungszeit dann doch noch ein brauchbares Ergebnis sehen. Der Start dauert >3 ms bis die 3,3 Volt erreicht sind. Dann sieht alles normal aus.

Um alle Störfaktoren auszuschalten hatte ich die Impulsstromsenke abgekniffen. Nun da alles Funktioniert miot einem neuen Timing ein neuer Versuch:

Sonderbarer Weise schaft es die Schaltung nicht die Last von 1,5A auszuregeln. Bei den vorherigen Simulationen funktionierte das einwandfrei.

Das Problem hat der Elko C5 mit 220µF gemacht, den ich bei den ersten Simulationen mit einem OP hinzugefügt hatte, um den Rippel zu reduzieren. Warum dort das Problem nicht aufgetreten ist, erschließt sich mir nicht.

Mit nur 22µF funktioniert es wie es soll. Die FB-Spannung habe ich ausgeblendet weilsie sonst alles andere überdeckt.

Nun ist der Rippel wieder größer aber die Schaltung funktioniert.

Hier wurde C1 von 22 auf 100 µF erhöht. Das funktioniert auch noch Problemlos. Der Spannungseinbruch bei Last ist < 20 mV.
Der Schaltplan der obigen Simulation.

Einen LDO-Regler nachschalten

Es wird empfohlen für eine besonders saubere Spannung einen analogen LDO-Regler nachzuschalten. Das wollte ich natürlich auch simulieren.

Links: