Just for fun, let me post a few notices about my failed K2000/K2001 display replacement ...
Files say I started it somewhere in 2021, at least first attempts to get an idea how display work and how to get something similar.
My goal was to make whole display assembly, not just replace failed VFD ...
For protocols, in both cases they work like terminals ...
Commands
0x0B 0x00 - set non-blinking
0x0B 0x01 - set blinking
0x0B 0x02 - lower light intensity
This also survices carriage moving
0x04 0x00 - ??? frequently at the beginning of text
Maybe argument is offset ???
002 2 02 STX (start of text) remove all after current position and print text
003 3 03 ETX (end of text) remove all before current position and print text
0x04 with offset - where to start writing ...
0x05 - backspace
0x06 0xXX 0xXX - light up upper annunciators line, 16 of total
0x07 0xXX 0xXX - turn off upper annunciators line
0xc ???
0xD - carriage return, nothing is cleaned
Cannot find how to enable numbers :(
Blinking timing ... maybe make smth like 0.45s
Buttons scanning:
Usually one of the lines is high all the time. Maybe that is in order to detect most common buttons, not sure.
Once in ~20 ms it goes down and on other lines 10us scan is performed.
If pressed button is detected, wait for 40ms and confirm it - it likely uses trigger on failing edge as well here.
if button was pressed all the time - send it's code and wait for unpress.
Button is sent as it's singe byte code, and when unpressed - 0x40 '@' is sent.
...
s.write('\x04\x0a\x03') - some bug, panel starts drawing more current and do not respond to input ...
...
fun note for K2000 panel
CMD 12 - also some even more weird blinking
sets NEXT EXISTING symbol to be blinking if 1, 0 if not, NO SHADOW
IF symbol is already blinkng, 12 1 makes it appear/disappear !!!
BUT, makes ONLY LAST symbol entered, so if before was blinking, it clears it (only the one set for 12 cmd)
Likely that's all a BUG, but
>>>
>>> s.write([0x0f])
1
>>> s.write([11, 1])
2
>>> s.write([0x0D, '1', 12, 1, 5 , 0x5, 0, '0', '2'])
makes some annunciators BLINK !!! works w/o 12, 1, as well
By just executing 0x5 can make annunciators appear/disappear
In this case carriage go in reverse direction
Which was translated into:
/* Copyright chekhov at eevblog.com */
#pragma once
/* Commands for K2001-style display */
#define K2001_CMD_NONE 0x00
#define K2001_CMD_UNUSED_1 0x01
#define K2001_CMD_CLEAR_REST 0x02
#define K2001_CMD_CLEAR_BEFORE 0x03
#define K2001_CMD_SEEK 0x04
#define K2001_CMD_BACKSPACE 0x05
#define K2001_CMD_ANON_ON 0x06
#define K2001_CMD_ANON_OFF 0x07
#define K2001_CMD_UNUSED_8 0x08
#define K2001_CMD_UNUSED_9 0x09
#define K2001_CMD_UNUSED_A 0x0A
#define K2001_CMD_TEXT_MODE 0x0B
#define K2001_CMD_CARRIAGE_RETURN 0x0D
#define K2001_CMD_VERSION 0x0F
/* Bits that describe anonciators for K2001-style display */
#define K2001_DISP_ANON_EDIT 0x01
#define K2001_DISP_ANON_ERR 0x02
#define K2001_DISP_ANON_REM 0x04
#define K2001_DISP_ANON_TALK 0x08
#define K2001_DISP_ANON_LSTN 0x10
#define K2001_DISP_ANON_SQR 0x20
#define K2001_DISP_ANON_REAR 0x40
#define K2001_DISP_ANON_REL 0x80
#define K2001_DISP_ANON_FILT 0x0100
#define K2001_DISP_ANON_MATH 0x0200
#define K2001_DISP_ANON_4W 0x0400
#define K2001_DISP_ANON_AUTO 0x0800
#define K2001_DISP_ANON_ARM 0x1000
#define K2001_DISP_ANON_TRIG 0x2000
#define K2001_DISP_ANON_STAR 0x4000
#define K2001_DISP_ANON_SMPL 0x8000
/* Key values */
#define K2001_KEY_NONE '\0'
#define K2001_KEY_UP 'A'
#define K2001_KEY_TEMP 'B'
#define K2001_KEY_LEFT 'C'
#define K2001_KEY_MENU 'D'
#define K2001_KEY_ACI 'E'
#define K2001_KEY_STORE 'F'
#define K2001_KEY_LOCAL 'G'
#define K2001_KEY_NEXT 'H'
#define K2001_KEY_AUTO 'I'
#define K2001_KEY_RIGHT 'J'
#define K2001_KEY_EXIT 'K'
#define K2001_KEY_OHM_2 'L'
#define K2001_KEY_RECALL 'M'
#define K2001_KEY_CHAN 'N'
#define K2001_KEY_DCV 'O'
#define K2001_KEY_PREV 'P'
#define K2001_KEY_DOWN 'Q'
#define K2001_KEY_ENTER 'R'
#define K2001_KEY_OHM_4 'S'
#define K2001_KEY_FILTER 'T'
#define K2001_KEY_SCAN 'U'
#define K2001_KEY_ACV 'V'
#define K2001_KEY_REL 'W'
#define K2001_KEY_CAL 'Y'
#define K2001_KEY_FREQ 'Z'
#define K2001_KEY_MATH '['
#define K2001_KEY_CONFIG '\\'
#define K2001_KEY_DCI ']'
#define K2001_KEY_TRIG '^'
#define K2001_KEY_INFO '_'
(copyright is for fun, so I indeed believed I can make it and share here ...)
This was my first touch of STM32, so obvious choice was cheap knock-off (appeared to be) of STM32F103C8T6.
For display I've got OLED 3.12" 256x64 one from buydisplay, which at the end was main reason why it all failed.
It wasn't easy from several points of view:
* refresh rate is 50 Hz, so one needs to draw FAST. First attempts were made to use u8g2 library, which is great by itself but absolute disaster for this application - slow and inefficient.
* where to get font ? that was a nightmare, attempt to squeeze everything into this tiny display, keep some proportions, where to put this **** annunciators (I have this word, always spell wrongly).
* how to get along with this STM32 at all, at the end sending data w/o DMA was also too slow. My very first code was written in Arduino IDE, then had to switch to STM configurator.
With coding main issues were speed and correctness. Had to store fonts in bytes (comparing to compressed format u8g2 and similar libraries use) and draw it by hand, each symbol, font itself and procedures to do that at screen. And depending on application, annunciators may have had different font.

Will attach more photos when find them ...