Vor ein paar Wochen habe ich hier den TC1 Multifunction Tester mit der quelloffenen m-firmware geflasht. Seitdem liegt ein zweiter Bauteiltester aus genau dem gleichen Dunstkreis bei mir auf dem Tisch: ein LCR-T4-Plus mit gelber Platine, eingebautem ZIF-Sockel und Beschriftung „91make.taobao.com“ auf der Rückseite. Das billige Gegenstück zum TC1, vom selben Hersteller-Cluster, gleiche Firmware-Familie. Eigentlich ein gemütlicher Folge-Sonntag, dachte ich.

Zur Vorgeschichte gehört ein erster T4-Plus, den ich vor Jahren mal gekauft hatte. Das Gerät arbeitet bis heute, sein Display allerdings ist tot. Der COG-Controller unter dem Epoxy-Klecks auf dem ST7565R hat aufgegeben, der MCU lebt noch, aber zeigen kann er nichts mehr. Vor ein paar Wochen habe ich aus einer Resterampe ein zweites Exemplar geordert, gleicher Aufdruck, gleiche PCB-Revision. Plan: einmal Backup-Flash und dann beide Geräte parallel mit m-firmware betreiben, eines als Bastelreserve.
Aus „schnell mal das gleiche Flash-Profil wie beim ersten T4-Plus drüberbügeln“ wurde ein ganzer Nachmittag mit komplett schwarzem Display, abgeschnittenem Cursor, einem Tester der sich beim Loslassen des Buttons sofort wieder ausschaltet und am Ende der Erkenntnis, dass die zentrale Falle nicht in der Firmware steckt, sondern in einem winzigen Bauteil neben dem MCU.
Was steckt im T4-Plus v2?
Anders als der TC1 mit seinen zwei Chips (ATmega plus STC für das Power-Management) ist der T4-Plus ein Single-MCU-Design. Auf der Rückseite klebt genau ein nennenswerter Halbleiter, der Rest ist Spannungsteiler, drei Transistoren für die Power-Latch-Schaltung und der Quartz.


U1: ATmega328P-U-TH im TQFP-32-Gehäuse, Signatur 0x1e950f, 32 KB Flash, 2 KB SRAM, 1 KB EEPROM. Der Date-Code 2009SG8 stammt aus 2020, Production-Code-Pattern passt zu echtem Microchip-Silizium. Auf gefälschten Klonen sieht das Lasermarkings-Pattern deutlich anders aus, das Schriftbild ist hier sauber, also passt das.
Der Display-Controller sitzt unter dem schwarzen Epoxy-Blob auf dem LCD selbst und ist ein ST7565R mit 128 mal 64 Pixel monochromem STN-Panel, gelb-grüne Hintergrundbeleuchtung. Klassische COG-Bauform. Daten kommen seriell über vier GPIO-Leitungen rein. Kein I2C, sondern SPI-Bitbang vom MCU getrieben.
Stromversorgung läuft über einen 9V-Block mit Spannungsteiler 10k zu 3.3k auf einem ADC-Pin. Bedienelement: ein einziger blauer Start-Button, kein Drehgeber, kein IR-Empfänger, kein USB. Das Ding ist ein Wegwerf-Standalone im besten Sinne, nichts dran was schiefgehen kann.
Und dann ist da noch dieser kleine silberne Quartzblock direkt neben dem MCU. 8.000 steht da. Acht Megahertz. Beim ersten T4-Plus von vor Jahren habe ich 16 MHz im Hinterkopf, ich notiere mir die 8 MHz pflichtbewusst, denke aber „nett, anderer Quartz“ und mache ansonsten erstmal weiter. Spoiler: genau dieser Eintrag wird Stunden später zum Schlüssel.
ISP-Header finden, und der Aufdruck lügt
Der ISP-Header sitzt versteckt unter der Display-Platine, ein simples 2×3-Pad-Grid ohne aufgelötete Stiftleiste. Auf der Rückseite finden sich Silkscreen-Hinweise: mis, mosi, sck, reset, plus die beiden Stromversorgungspads. Lustig: bei diesem Board sind die beiden Datenleitungen vertauscht beschriftet. Was als mis markiert ist, trägt physisch MOSI; das mosi-Pad ist tatsächlich MISO.
Aufgefallen ist mir das beim ersten Signatur-Read mit dem Arduino Uno als ISP-Programmer. Wenn man stur nach Silkscreen verkabelt, antwortet der Chip mit lauter 0x00. Sobald die Leitungen getauscht werden, kommt eine saubere Signatur. Heißt für die Praxis: bei diesem Board nicht auf den Aufdruck verlassen, sondern Pin für Pin mit dem Durchgangsprüfer gegen die Chip-Pins verifizieren. Standard-ISP-Pinout auf dem ATmega328P im TQFP-32 ist Pin 17 MOSI, Pin 18 MISO, Pin 19 SCK, Pin 29 /RESET.

Verkabelung an den richtigen Pads (Arduino-seitig), gilt für beide T4-Plus-Boards:
Arduino D10 -> RESET (T4-Plus Pad RESET) Arduino D11 -> MOSI (T4-Plus Pad „mis" bei diesem Klon!) Arduino D12 -> MISO (T4-Plus Pad „mosi" bei diesem Klon!) Arduino D13 -> SCK (T4-Plus Pad SCK) Arduino 5V -> VCC Arduino GND -> GND
Sobald die Signatur sauber kommt, ist die halbe Miete drin:
$ avrdude -c avrisp -p m328p -P /dev/ttyACM0 -b 19200 -B 32 -v 2>&1 | grep -i sig avrdude: Device signature = 0x1e950f (probably m328p)
Backup der Original-Firmware
Beim TC1 ging das Backup nicht, weil die Lock-Bits auf 0xC0 standen und das Auslesen geblockt haben. Beim T4-Plus v2 habe ich Glück: Lock-Byte ist 0xFF, also komplett offen. Vor dem ersten Flash zieht man sich also bitte unbedingt das Original einmal komplett herunter, Flash und EEPROM:
avrdude -c avrisp -p m328p -P /dev/ttyACM0 -b 19200 -B 32
-U flash:r:t4plus2-original-flash.hex:i
-U eeprom:r:t4plus2-original-eeprom.hex:i
-U lfuse:r:-:h -U hfuse:r:-:h -U efuse:r:-:h -U lock:r:-:h
Fuses kamen so zurück: lfuse=0xF7, hfuse=0xD9, efuse=0xFD, lock=0xFF. Hat man das im Kasten, kann man auch beruhigt herumprobieren. Notfalls geht es per avrdude -U flash:w: jederzeit wieder auf den Auslieferungszustand zurück.
Erster Flash und ein völlig schwarzes Display
Quelle für die neue Firmware ist wie beim TC1 die m-firmware von madires, aktuell Version 1.56m. Im Repo liegt unter Software/Firmware/m-firmware/ der Source mit allen Config-Templates für die diversen MCU-Varianten. Für den ATmega328P ist das config_328.h, gemeinsame Optionen in config.h, build-Flags im Makefile.
Mein erster Anlauf orientierte sich an dem, was beim ersten T4-Plus damals funktioniert hatte. Display ST7565R aktivieren, BAT_DIVIDER mit 10k zu 3.3k, Short-Circuit-Menu an, MCU auf atmega328 (ohne das nachgeschobene P, sonst greift der #if defined(__AVR_ATmega328__)-Guard in config_328.h nicht und der Build wirft undefinierte BUTTON_PIN-Symbole), Frequenz pflichtbewusst auf FREQ = 16 wie beim ersten Board.
Make, flash, einschalten, und dann das hier:

Komplett schwarz. Kein Boot-Banner, keine Kontrast-Stufe, einfach nur eine schwarze Fläche. Mein erster Gedanke war natürlich: Display kaputt, gleicher Spaß wie beim ersten T4-Plus. Aber die Backlight-LEDs leuchten, und im Streiflicht erkennt man, dass die Pixel-Anordnung sichtbar ist, nur eben in „alle Pixel an“-Stellung. Das ist kein toter Controller, das ist ein lebender Controller mit zu hohem internem LCD-Bias.
Im m-firmware-Source liegt direkt ein Clones-Verzeichnis mit Hinweisen zu bekannten Klon-Variationen. Für den verwandten LCR-T5 steht dort genau dieser Workaround: bei manchen ST7565R-Panels ist der per Software gesetzte Bias zu hoch, der typische Default-Befehl CMD_V0_RATIO | FLAG_RATIO_65 muss runter auf FLAG_RATIO_55 oder sogar FLAG_RATIO_45. Geändert wird das in ST7565R.c in der Funktion LCD_Init():
/* set contrast: resistor ratio 5.5 */ LCD_Cmd(CMD_V0_RATIO | FLAG_RATIO_55); /* statt FLAG_RATIO_65 */
Mit dieser einen Zeile ändert sich alles. Neuer Build, flashen, und siehe da, plötzlich sind tatsächlich Pixel sichtbar.
Display-Tuning: Orientierung, Kontrast und der abgeschnittene Cursor
„Pixel sichtbar“ heißt noch lange nicht „lesbar“. Was da auf dem Display erscheint, sind erstmal Hieroglyphen kopfüber, spiegelverkehrt, mit komischen Pixel-Mustern an Stellen, an denen eigentlich Zeichen stehen sollten. Das ist die klassische ST7565R-Inbetriebnahme: drei Defines steuern Orientierung und Kontrast, alle drei muss man am eigenen Panel kalibrieren.
//#define LCD_FLIP_X /* horizontale Spiegelung */ //#define LCD_FLIP_Y /* vertikale Spiegelung */ #define LCD_CONTRAST 22 /* 0..63, 22 passt hier */
Bei meinem Panel sind beide FLIP-Defines aus, was unintuitiv klingt aber stimmt. Der Kontrast landet final bei 22. Nach ein paar Build-Iterationen sieht das so aus:

Klassischer Fall: bestimmte ST7565R-Panel-Varianten brauchen einen X-Offset von vier Pixel, weil deren sichtbarer Bereich rechts beginnt. Andere wiederum nicht. Das Define LCD_OFFSET_X erzwingt genau diese Verschiebung. Mein Panel will sie nicht, also raus damit:
//#define LCD_OFFSET_X /* deaktiviert: kein +4 Pixel Shift */

An dieser Stelle wäre die Geschichte normalerweise vorbei. Display tut, Buttons drücken, Messen, fertig. Wäre da nicht das Problem mit dem Einschalten.
Das Power-Latch-Drama
Der T4-Plus hat einen blauen Druckknopf. Den drückt man, der Tester bootet, misst, schaltet sich nach Inaktivität von alleine wieder ab. So weit der Plan. Mein frisch geflashtes Board allerdings macht etwas Ärgerliches: Knopf drücken, Display bootet kurz an, Knopf loslassen, sofort wieder aus. Das ist kein „Auto-Power-Off nach Timeout“, das ist „MCU verliert beim Loslassen die Stromversorgung“. Klassischer Power-Latch-Bug.
Erster Reflex: irgendein POWER_CTRL-Pin in der Config ist falsch. Die m-firmware hat einen Define für den Pin, an dem der MCU nach dem Boot ein HIGH-Signal anlegen muss, um sich selbst am Leben zu halten. Auf den meisten Boards heißt der Pin PD6 oder ähnlich. Also durchprobiert: PD6, PD7, PD4, PD3, alles was an freien Pins noch übrig ist. Kein Erfolg. Egal welcher Pin, sobald der Finger den Button verlässt, ist Schluss.
Zeit für die Multimeter-Tour über die Latch-Schaltung. Auf der Platine sitzen drei Transistoren um den Power-Knopf herum: Q1 ist ein S9015 (PNP), schaltet die 9V auf die Versorgung. Q2 und Q3 sind beide S9014 (NPN) und treiben gemeinsam mit dem Button-Kontakt die Basis von Q1. Durchgangsmessungen ergeben:
Pin 29 (/RESET) --- 27 kOhm --- Basis Q3 Basis Q3 --- Button-Kontakt --- GND Kollektor Q3 --- Basis Q1 (über Pull-up) Q1 schaltet 9V auf den 5V-Regler
Das ist also gar kein „Firmware schaltet POWER_CTRL HIGH“-Design. Die Latch-Schaltung ist passiv über die /RESET-Leitung des MCU aufgebaut. Solange der ATmega läuft, liegt /RESET auf HIGH (intern hochgehalten), und über den 27k zur Basis von Q3 bleibt der Transistor durchgesteuert, Q1 hält die Versorgung an. Drückt man den Button, zieht der Q3-Basis kurz auf GND-Potenzial Richtung positiv und triggert das Hochfahren über einen leicht anderen Pfad. Aber sobald der Boot durch ist und der MCU /RESET HIGH hält, läuft das Ganze von alleine.
Heißt: an meinem Board sollte das auch ohne firmware-seitiges POWER_CTRL funktionieren. Tut es aber nicht. Spannungsmessung unter Strom zeigt: Q3-Basis bleibt dauerhaft bei 0V, der Transistor schaltet nie sauber durch. Aber warum, wenn doch /RESET nach erfolgreichem Boot eigentlich HIGH sein müsste?
An dieser Stelle saß ich gefühlte zwei Stunden an dem Tisch und habe mit dem Multimeter zwischen MCU-Pinout, Transistor-Basen und 9V-Schiene hin- und hergemessen. Mein Verdacht war zwischendurch ein toter Transistor, ein kalter Lötpunkt, ein verkokelter Trace unter dem schwarzen Lötstopplack. Alles falsch.
Der Aha-Moment im Makefile eines fremden Forks
Irgendwann habe ich aus Verzweiflung angefangen, fremde Firmware-Forks für genau dieses Board zu lesen. Es gibt eine zweite quelloffene Linie neben der m-firmware: die k-firmware (das „k“ steht für Karl-Heinz Kübbeler, den Original-Autor), und davon wiederum diverse Forks. Einer davon ist Palingenesis‘ Fork mit einem dedizierten T4-v2-Build-Profil. Ich öffne dessen Makefile, und der Blick fällt auf eine einzelne Zeile:
OP_MHZ = 8
Acht. Megahertz. Genau die Zahl, die ich Stunden vorher auf dem Quartz gelesen und in mein Notizfeld geschrieben hatte. Genau die Zahl, deren Bedeutung ich nicht richtig zu Ende gedacht hatte. Mein Build der m-firmware lief mit FREQ = 16, weil ich davon ausgegangen war, dass das T4-Plus-Board immer 16 MHz Quartz hat. Tut es eben nicht. Beim zweiten Exemplar ist ein 8-MHz-Quartz drauf.
Was das praktisch bedeutet: wenn die Firmware glaubt, sie laufe auf 16 MHz, aber tatsächlich nur 8 MHz Takt verfügbar sind, läuft jede Operation effektiv mit halber Geschwindigkeit. Jedes Timer-Tick, jede Schleife, jede ADC-Konversion dauert doppelt so lang. Im Falle der Initialisierungssequenz heißt das: bis der MCU im Bootcode an der Stelle ist, an der POWER_CTRL HIGH gesetzt wird (oder bis /RESET stabil HIGH ausgegeben wird), ist das Zeitfenster, in dem der Button noch gedrückt ist, schon längst vorbei. Der Latch greift nicht, der Tester schaltet sich beim Loslassen ab.
Drei Buchstaben im Makefile geändert:
FREQ = 8
Neu kompiliert, geflasht. Knopf gedrückt. Display kommt. Knopf losgelassen. Display bleibt an. Der Tester hält sich selbst am Leben. Zwei Stunden Diagnose-Drama wegen einer einzigen Zahl im Makefile, die mit der eigentlichen Hardware nichts zu tun hatte, außer dass die Hardware halt ein anderer Quartz war als gedacht. Genau eine dieser Stellen, an denen man kurz aufsteht und sich was zu trinken holt.
Self-Adjustment und Werte ins Flash schreiben
Nach dem Power-Latch-Fix ist der Tester quasi nutzbar, aber die m-firmware meldet beim Boot „Checksum failure“ für die Adjustment-Werte im Flash. Das ist erwartbar, weil dort ja noch nie eigene Kalibrierwerte gespeichert wurden. Heilmittel: das Service-Menü aufrufen, Self-Adjustment durchlaufen, Werte abspeichern.
Voraussetzung ist, dass UI_SHORT_CIRCUIT_MENU in config.h aktiviert ist. Damit kommt man ins Menü, indem man beim Start alle drei Probes (1, 2, 3) miteinander kurzschließt. Der Tester erkennt das und blendet das Service-Menü ein:

Erster Punkt ist „Test“, ein Selbsttest mit allen drei Probes. Anschließend „Adjustment“, da braucht man dann einen 1 µF-Kondensator zwischen Probe 1 und Probe 3. Der Tester misst seinen eigenen internen Ri-Wert, die Eingangskapazität, eine Referenzspannung. Am Ende „Save“, und die Werte landen via DATA_FLASH als Block im Programmspeicher (Self-Programming). Beim TC1 war das genauso, der einzige Unterschied: dort kommen die Daten in den 1 KB EEPROM. Beim T4-Plus reicht der Flash-Bereich und ich nutze DATA_FLASH stattdessen, weil das Self-Programming auf dem ATmega328P stabiler läuft als die EEPROM-Erase-Write-Sequenz.

Diese Werte unterscheiden sich übrigens leicht von Board zu Board. Die Ri-Werte hängen an den konkreten Innenwiderständen der MCU-Ausgangsstufen, C0 und R0 an den Probe-Leitungslängen, Vref am internen Bandgap. Wer die Hex eines anderen Geräts mit dessen Flash-Region 1:1 auf sein eigenes flasht, übernimmt also fremde Kalibrierdaten, die zu falscher Mess-Anzeige führen können. Lieber einmal selbst kalibrieren.
3D-gedrucktes Gehäuse statt nackte Platine
Das Original-T4-Plus kommt ohne Gehäuse, nur die nackte Platine. Für den TC1 gab es ja damals zumindest noch eine billige Plastik-Halbschale, hier ist nicht mal das dabei. Auf Makerworld liegt ein passendes Modell von „LeoNerd“ mit der ID 1891431, „Case for LCR-T4 Component Tester“. Drei Teile: Unterschale, Frontblende mit ZIF-Sockel-Ausschnitt und Display-Fenster, Batterie-Klappe.
Ich habe das auf meinem Bambu Lab X1 Carbon in PETG ausgedruckt. PLA ginge auch, aber PETG ist hier ein bisschen weniger spröde, der Tester wird ja immer wieder mal in die Hand genommen. Maße passen direkt, das PCB sitzt sauber zwischen den Stegen, das Display fluchtet, der Button schaut zentrisch durch die Öffnung. Den 9V-Block fixiert die Klappe von hinten.
Finaler Funktionstest im Gehäuse


Ein paar Testmessungen mit Bauteilen aus der Schublade: 10k-Widerstände, ein paar 100 nF Kondensatoren, ein BC547 und ein paar LEDs. Alle Werte plausibel, BC547 wird mit korrekter Pin-Zuordnung als NPN-Transistor erkannt, hFE in der erwarteten Größenordnung. Damit ist das Gerät einsatzbereit.
Die finale Konfiguration zum Mitnehmen
Damit andere mit dem gleichen 91make-Klon nicht die gleichen drei Tage verbrennen müssen, hier alle Änderungen relativ zur unveränderten m-firmware 1.56m an einer Stelle gesammelt.
Makefile (Auszug, nur die geänderten Zeilen):
MCU = atmega328 # NICHT atmega328p, sonst greift der Include-Guard nicht FREQ = 8 # 8 MHz Quartz auf der v2-Variante, nicht 16 PARTNO = m328p # avrdude-Part bleibt m328p
config.h (gemeinsame Optionen, aktive Defines):
#define HW_REF25 /* interne 2.5V-Bandgap-Referenz */ #define UI_AUTOHOLD /* nach Messung auf Tastendruck warten */ #define UI_SHORT_CIRCUIT_MENU /* Service-Menue via 3-Probe-Short */ #define POWER_OFF_TIMEOUT 60 /* Auto-Off nach 60 Sekunden Idle */ #define BAT_DIVIDER /* externer 10k/3.3k-Teiler */ #define BAT_R1 10000 #define BAT_R2 3300 #define BAT_WEAK 7400 /* 7.4V Warnschwelle */ #define BAT_LOW 6400 /* 6.4V Abschaltschwelle */ #define DATA_FLASH /* Kalibrierdaten ins Programm-Flash */
config_328.h (ST7565R-Section, alles relevante an einem Stueck):
#define LCD_ST7565R #define LCD_GRAPHIC #define LCD_SPI #define LCD_PORT PORTD #define LCD_DDR DDRD #define LCD_RESET PD0 #define LCD_CS PD5 #define LCD_A0 PD1 #define LCD_SCL PD2 #define LCD_SI PD3 #define LCD_DOTS_X 128 #define LCD_DOTS_Y 64 //#define LCD_OFFSET_X /* AUS, sonst +4 Pixel Verschiebung */ //#define LCD_FLIP_X /* AUS */ //#define LCD_FLIP_Y /* AUS */ #define LCD_START_Y 0 #define LCD_CONTRAST 22 #define FONT_8X8_VF #define SYMBOLS_24X24_VFP #define SPI_BITBANG
ST7565R.c (genau eine Zeile in LCD_Init()):
/* set contrast: resistor ratio 5.5 */ LCD_Cmd(CMD_V0_RATIO | FLAG_RATIO_55); /* war FLAG_RATIO_65 */
Flash-Befehl, identisch zum TC1 (nur die Hex-Datei ist eine andere):
avrdude -c avrisp -p m328p -P /dev/ttyACM0 -b 19200 -B 32
-U flash:w:ComponentTester.hex:i
Was ich aus dem Nachmittag mitnehme
Vier Punkte, die ich beim nächsten Klon-Tester sofort prüfen werde, statt wieder Stunden in der Diagnose zu verbringen:
- Quartz mit der Lupe lesen bevor man die Frequenz im Makefile setzt. Identische PCB-Bezeichnung garantiert nicht den gleichen Takt. Bei diesem T4-Plus ist es 8 MHz, bei meinem ersten waren es 16 MHz. Zwei Boards, derselbe Aufdruck, verschiedene Bestückung.
- ST7565R komplett schwarz nach erstem Flash ist fast immer ein zu hoher Bias und kein toter Controller. Erst
FLAG_RATIO_65aufFLAG_RATIO_55oderFLAG_RATIO_45ändern, dann weiter denken. - Silkscreen-Labels glauben, aber verifizieren. Auf dem v2-Board sind
misundmosiphysisch vertauscht. Einmal Durchgangsprüfung gegen den MCU-Pin spart eine Stunde Frustration. - Vermeintliche Hardware-Fehler sind manchmal Build-Parameter. Ein Tester, der sich beim Loslassen ausschaltet, sieht aus wie eine kaputte Latch-Schaltung. War aber in Wirklichkeit nur die falsche CPU-Frequenz im Makefile, was den Boot-Code langsamer laufen ließ, als das mechanische Button-Zeitfenster es zuließ.
Repo und Quellen
Wie beim TC1 habe ich auch hier ein kleines Repo mit der fertigen Hex, den Config-Patches und einer README mit Schritt-für-Schritt-Anleitung gepackt: github.com/Kernel-Error/t4plus-v2-firmware-update. Lizenz folgt der m-firmware (EUPL v1.2), die Config-Patches sind als unified diff gegen die unveränderte 1.56m beigelegt.
Quellen, ohne die das nicht funktioniert hätte:
- m-firmware (Madires/Transistortester-Warehouse), die Quelle der Firmware, inklusive
Clones-Verzeichnis mit den Hinweisen zum LCR-T5-FLAG_RATIO-Workaround - k-firmware (Kübbeler), der ältere Original-Branch von Karl-Heinz Kübbeler
- Instructables „LCR-T4 Upgrade“ von Palingenesis, der den entscheidenden Hinweis auf 8 MHz im Makefile-Profil hatte
- AVR Transistortester auf mikrocontroller.net, der deutschsprachige Hintergrundartikel zum gesamten Projekt
- 3D-Gehäuse auf Makerworld, drei Teile, passt direkt
Siehe auch: TC1 Multifunction Tester mit Open-Source-Firmware (der Vorgänger-Beitrag, gleiche Firmware-Familie, mehr Drama bei der STC-Variante), Multifunktionstester für Elektronikbauteile (mein erster Eindruck von dieser Tester-Klasse 2019), xum1541-Firmware-Bug gefunden und gefixt (anderes Mikrocontroller-Firmware-Drama), OSSC Firmware-Update 1.21 (Firmware-Update an Open-Source-Hardware), Preciva 992D+ Lötstation (für alle die nach diesem Beitrag selber löten wollen).
Fragen, eigene T4-Plus-Klon-Varianten oder noch krummere Silkscreen-Vertauschungen gesehen? Gerne über die fragen-Seite oder als Issue im Repo.

Schreibe einen Kommentar