Advantest R6581 VFD replacement - Page 1
Forum section: electronics / repair

author: Mickle T.
author_rank: Frequent Contributor
timestamp: September 08, 2024, 08:29:54 am
content: As is well known, the Advantest R6581 DMM has two main problems, the second of which is a custom VFD display that is not available commercially.As a result of reverse engineering the multimeter firmware and analyzing the circuit diagram, I was able to find at least two possible ways to replace the VFD that has become unusable:1) A difficult to implement, but flexible and interesting way: installing a microcontroller module that "spy" on reading the external dual-port display buffer from the Hitachi H8 controller on the front panel board. The resulting ASCII character codes and their attributes can be rendered on any graphic display.2) A simple and cheap to implement way: installing a microcontroller module that "spy" on writing to the shift registers on the front panel board of the multimeter. The resulting bit image of characters can be output only to a limited number of displays with a resolution of at least 256x48 pixels.If you choose the second way (which is what I did), then replacing the display will cost about $20 and half an hour of your time. As a basis, I took the most common STM32 Blue Pill (STM32F103C8T6) and 3.12" OLED with SSD1322 controller. Attached is the schematic diagram and the project archive in STM32CubeIDE.

author: TheDefpom
author_rank: Frequent Contributor
timestamp: September 09, 2024, 08:54:56 am
content: That is excellent, thank you for providing this !Now I just need to figure out how to use the STM32 IDE and get a blue pill board and ST-link.I've never used an STM32 so a bit of STM32 learning is in my near future, which is probably a good thing anyway !

author: dietert1
author_rank: Super Contributor
timestamp: September 27, 2024, 07:29:37 am
content: In another thread a 4.58" TFT bar display was proposed as a possible replacement. In comparison to original VFD it might look like this. Don't know yet how it fits inside the R6581.The controller uses a STM32H730 and its LTDC peripheral. It fits to the back of the TFT. At 300 MHz the MCU needs about 5 msec to paint the image in its video memory. TFT refresh rate came out as 41 Hz.Regards, Dieter

author: dietert1
author_rank: Super Contributor
timestamp: September 28, 2024, 07:08:18 pm
content: Thanks to Mickle T.s great reengineering it was fairly easy to connect the TFT display to one of our R6581. Also i unmounted the R6581 display board to check available space. The TFT and its controller can become one module and fit very similar to the original VFD.The firmware reads all display data packets and paints each one of them, so there is no visible delay in comparison to the VFD. I also added kind of OCR to the firmware. Right now it only recognizes that strange "DISPLAY OFF" message and turns the TFT backlight off. Maybe one can substitute the 5x7 matrix by a higher resolution font.Regards, Dieter

author: dietert1
author_rank: Super Contributor
timestamp: September 29, 2024, 02:10:49 pm
content: In order to train the OCR i would like to post various text messages to the R6581 display via GPIB. Many GPIB devices support some kind of message display but i couldn't find the proper GPIB command in the R6581 manual. Who can help with hint?Regards, Dieter

author: Mickle T.
author_rank: Frequent Contributor
timestamp: September 29, 2024, 02:43:43 pm
content: The original, unmodified firmware does not contain commands for text output and complete blanking of the display.

author: dietert1
author_rank: Super Contributor
timestamp: October 09, 2024, 08:57:05 am
content: Unsoldering the original VFD display was quite some exercise. Meanwhile some brackets (3D printed) were glued to the boards as support for the 4.58" TFT display and its graphics card. A narrow fit!By the way: The VFD cathodes need about 4 W for heating, while the TFT needs about 20 mA x 12 V = 240 mW for its backlight plus 150 mW for the graphics card. Roughly a 10x reduction.Regards, Dieter

author: dietert1
author_rank: Super Contributor
timestamp: October 11, 2024, 03:13:45 pm
content: First image shows the +12 V backlight supply. It has a voltage doubler and a LM7812.Meanwhile i finished two R6581T with the replacement TFT display.The interesting number in the image is the upper one with 15.57 uV. This is with an 18 MOhm resistor and a 1 uF cap across input, so input offset current < 1 pA. That R6581T got a mosfet input mux. The other one got a mains preregulator similar to the Keithley 2002. So there is more work to do..Regards, Dieter

author: kjk24
author_rank: Regular Contributor
timestamp: October 11, 2024, 06:28:40 pm
content: Thank you 👍 verry much

author: TheDefpom
author_rank: Frequent Contributor
timestamp: October 13, 2024, 04:30:40 am
content: Well thanks to Mickle T. I have now replaced my display with a 3.12" OLED, it was always in my plans to do something to replace it, and thankfully I didn't have to sit down for days trying to work it out !Not sure I went with the best colour, maybe I should have gone with Yellow instead, but it is still a lot better than it was.I am watching the 4.58" display version with interest (I have a display here already), as that would be even better as then the text would not need to be shortened, would also be nice to use a smoother font for the 5x7, but now I am just being picky LOL.I have recorded a video of the conversion which I will publish on my channel at some point, I didn't go into detail about the programming of the STM32, as I did that a couple of weeks ago (first time using an STM32), I might have to record something to fill that information gap.

author: IanJ
author_rank: Unknown
timestamp: October 15, 2024, 03:50:21 pm
content: Hi all,Just a wee note.......I have an R6581T on it's way, and Ithinkthe VFD is ok (famous last words!), but decided to put together one of these OLED solutions anyway. Those that know me will know I like modifying/upgrading my gear!I have the .HEX file and have uploaded it to one of my BluePill STM32 boards, however, in regards to the toolchain my app of choice is Visual Studio (I don't use Eclipse) for everything including Win apps in VB, Arduino ATMEGA & STM32, so decided to try VisualGDB plugin for Visual Studio (VS 2022) and lo & behold I was able to import Mickle T's source, set up the configuration and compile a .HEX file of my own.Looking forward to receiving my OLED and trying the original Mickle T HEX file as well as the one compiled by Visual Studio.....see if it works!Anyone else tried this?.......so far VS VisualGDB plugin is looking workable!UPDATE:No R6581T yet so scoped the STM32 pins with original HEX, got some waveforms, then uploaded my own HEX file from VS and scoping them again I get exact same waveforms, so looking good.Original HEX file = 29.6KBVS HEX file = 39.9KB, so I can only assume VS debugging overheads & optimization.I haven't started looking at Mickle T's source code at all, but looking forward to having a look around, and knowing me tweaking.UPDATE:The VS2022 compiled projectdoeswork with the R6581T & OLED.Ian.

author: TheDefpom
author_rank: Frequent Contributor
timestamp: October 19, 2024, 03:28:34 am
content: Here is my video about replacing the display on my unit:

author: IanJ
author_rank: Unknown
timestamp: October 19, 2024, 10:30:10 am
content: Hi all,Below is a link to my conversion of Mickle T's original source project to a Visual Studio project (Windows).It compiles to a hex file just fine..........Untested though, although the uploaded HEX file does seem to scope the same signals on the STM32 board.No source changes were necessary at all.VS2022 64-bit, Community EditionRequires VisualGDB plugin for VS (30-day demo version will do) -https://visualgdb.comhttps://github.com/Ian-Johnston/OLED_SSD1322_DMAIan.

author: dietert1
author_rank: Super Contributor
timestamp: October 28, 2024, 05:52:55 pm
content: Here is a zip archive with that H730 LTDC TFT replacement display project. As i have some ready to use PCBs left i thought about making them into kits, but i don't have time to support that.Regards, Dieter

author: IanJ
author_rank: Unknown
timestamp: October 28, 2024, 08:51:29 pm
content: Here's my OLED conversion photos below.And my YT video:https://youtu.be/QyP6tK9EIsgI also modified the OLED display (SSD1322 iREF pin) to increase the brightness just a touch to compensate for the smoked perspex. Instructions are in the video.A big thanks to Mickle T......what a difference this has made to my R6581T.Ian.

author: IanJ
author_rank: Unknown
timestamp: October 28, 2024, 09:17:06 pm
content: Quote from: dietert1 on October 28, 2024, 05:52:55 pmHi,Any chance you can export the gerbers?Looks like and older Eagle binary .brd file which Kicad etc can't open.Thanks,Ian.

author: dietert1
author_rank: Super Contributor
timestamp: October 28, 2024, 11:44:17 pm
content: Yes, it's Eagle version 4.16. Can't you just order the PCB using the board file? I never had to supply Gerber files. The PCB is four layers, size 65 x 40 mm.In case somebody wants to design his own PCB i added a schematic. R7 .. R12 are three voltage dividers for the 5V logic data inputs. Later i checked that those STM32H730 pins are 5 V tolerant and omitted R10 .. R12.Regards, Dieter

author: branadic
author_rank: Super Contributor
timestamp: November 07, 2024, 07:25:07 pm
content: QuoteWorkflow is easy, open it with Eagle 7 Lite, save it and you can import it to KiCAD. Attached is the Eagle 7 board file.-branadic-

author: IanJ
author_rank: Unknown
timestamp: November 16, 2024, 10:22:05 pm
content: Hi all,So far so good, a day spent on Visual Studio and I have mapped the incoming bitmap data to ASCII characters, getting ready for driving a TFT display.Screenshot attached, a live debug session in VS with the STM32 and that's "+ 1.2345638 VDC" appearing in the code (G1 to G18) from the R6581T.Next, I'll deal with the AUX display G19 to G47, and the annunciators after that.From there get a LT7680 TFT driver loaded and start send data to the new display and playing with fonts etc.Again, completely impossible without MickleT's great work on the original reverse engineering.PS. C is pretty new to me albeit I've done loads of C++, so it's not too far away.Ian.

author: IanJ
author_rank: Unknown
timestamp: November 17, 2024, 01:39:26 pm
content: Incase anyone is interested, here's my MAIN.C code which creates ASCII vars/arrays for the main, aux and annunciators.It's working as far as I can monitor the STM32 live vars in VS2022 and they are all working.There may be some individual ASCII character issues, I still need to verify some of them i.e. the lower case ones and adjust the hex accordingly.PS. I am not a software programmer, it's a WIP, so please be gentle!Next step is the TFT LCD driver......at which point I will disable the existing OLED I/O as I need the pins.Ian.Code:/********************************************************************************* @file : main.c* @brief : Main program body******************************************************************************* @attention** Copyright (c) 2024 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.******************************************************************************** Original code by MickleT, this version modded by IanJ,* for 4.58" 960x320 TFT LCD (ST7701S) and using LT7680 adaptor* Visual Studio 2022 with VisualGDB plugin:* To upload HEX from VS2022 = BUILD then PROGRAM AND START WITHOUT DEBUGGING* Use LIVE WATCH to view variables live debug**//* Includes ------------------------------------------------------------------*/#include "main.h"#include "dma.h"#include "spi.h"#include "gpio.h"#include <stdarg.h>#include <stdio.h>#include <string.h>#include <stdint.h>/* Private includes ----------------------------------------------------------*/#include "SSD1322_OLED_lib/SSD1322_HW_Driver.h"#include "SSD1322_OLED_lib/SSD1322_API.h"#include "SSD1322_OLED_lib/SSD1322_GFX.h"/* Private variables ---------------------------------------------------------*/static char main_display_debug[LINE1_LEN + 1]; // Main display debug string#define FONT_HEIGHT 7// Buffers for each LCD graphical itemchar LCD_buffer_packets; // For packet datachar LCD_buffer_bitmaps; // For decoded bitmap datachar LCD_buffer_chars; // For decoded characterschar G1, G2, G3, G4, G5, G6, G7, G8, G9, G10, G11, G12, G13, G14, G15, G16, G17, G18; // Mainchar G19, G20, G21, G22, G23, G24, G25, G26, G27, G28, G29, G30, G31, G32, G33, G34, G35, G36, G37, G38, G39, G40, G41, G42, G43, G44, G45, G46, G47; // Aux_Bool Annunciators; // Array for MAIN annunciators. The order on LCD left to right = 8,7,6,5,4,3,2,1,017,16,15,14,13,12,11,10,9_Bool AnnunciatorsReordered; // G1 to G18 in left-to-right order//******************************************************************************// SPI receive buffer for packets datavolatile uint8_t rx_buffer[PACKET_WIDTH*PACKET_COUNT];// Array with character bitmapsuint8_t chars;// Array with annunciators flags (boolean)uint8_t flags;// When scanning the display, the order of the characters output is not sequential due to optimization of the VFD PCB layout.// The Reorder[] array is used as a lookup table to determine the correct position of characters.const uint8_t Reorder = { 8, 7, 6, 5, 4, 3, 2, 1, 0, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 17, 16, 15, 14, 13, 12, 11, 10, 9, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36 };// Order of data to the display (effectively into the shift registers):// 8, 7, 6, 5, 4, 3, 2, 1, 0, // MAIN: G9 to G1// 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, // AUX: G19 to G36// 17, 16, 15, 14, 13, 12, 11, 10, 9, // MAIN: G18 to G10// 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36 // AUX: G47 to G37// But the actual display left to right:// G1 to G18 - MAIN// G19 to G47 - AUX// AnnunciatorsReordered to AnnunciatorsReordered// Used for line-by-line recoding and scaling of the characters of the main display line.// All 32 possible variants of a 5-pixel wide character bitmap string are converted into// the corresponding 10 OLED display pixels with 16 color gradations and packed into 5 bytes.const uint8_t Upscale1 = {{ 0x00, 0x00, 0x00, 0x00, 0 },{ 0x00, 0x00, 0x00, 0x00, 0xFF },{ 0x00, 0x00, 0x00, 0xFF, 0 },{ 0x00, 0x00, 0x00, 0xFF, 0xFF },{ 0x00, 0x00, 0xFF, 0x00, 0 },{ 0x00, 0x00, 0xFF, 0x00, 0xFF },{ 0x00, 0x00, 0xFF, 0xFF, 0 },{ 0x00, 0x00, 0xFF, 0xFF, 0xFF },{ 0x00, 0xFF, 0x00, 0x00, 0 },{ 0x00, 0xFF, 0x00, 0x00, 0xFF },{ 0x00, 0xFF, 0x00, 0xFF, 0 },{ 0x00, 0xFF, 0x00, 0xFF, 0xFF },{ 0x00, 0xFF, 0xFF, 0x00, 0 },{ 0x00, 0xFF, 0xFF, 0x00, 0xFF },{ 0x00, 0xFF, 0xFF, 0xFF, 0 },{ 0x00, 0xFF, 0xFF, 0xFF, 0xFF },{ 0xFF, 0x00, 0x00, 0x00, 0 },{ 0xFF, 0x00, 0x00, 0x00, 0xFF },{ 0xFF, 0x00, 0x00, 0xFF, 0 },{ 0xFF, 0x00, 0x00, 0xFF, 0xFF },{ 0xFF, 0x00, 0xFF, 0x00, 0 },{ 0xFF, 0x00, 0xFF, 0x00, 0xFF },{ 0xFF, 0x00, 0xFF, 0xFF, 0 },{ 0xFF, 0x00, 0xFF, 0xFF, 0xFF },{ 0xFF, 0xFF, 0x00, 0x00, 0 },{ 0xFF, 0xFF, 0x00, 0x00, 0xFF },{ 0xFF, 0xFF, 0x00, 0xFF, 0 },{ 0xFF, 0xFF, 0x00, 0xFF, 0xFF },{ 0xFF, 0xFF, 0xFF, 0x00, 0 },{ 0xFF, 0xFF, 0xFF, 0x00, 0xFF },{ 0xFF, 0xFF, 0xFF, 0xFF, 0 },{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }};// Used for line-by-line recoding and scaling of the characters of the auxiliary display line.// All 32 possible variants of a 5-pixel wide character bitmap string are converted into// the corresponding 5 OLED display pixels with 16 color gradations and packed into 3 bytes.const uint8_t Upscale2 = {{ 0x00, 0x00, 0x00 },{ 0x00, 0x00, 0xF0 },{ 0x00, 0x0F, 0x00 },{ 0x00, 0x0F, 0xF0 },{ 0x00, 0xF0, 0x00 },{ 0x00, 0xF0, 0xF0 },{ 0x00, 0xFF, 0x00 },{ 0x00, 0xFF, 0xF0 },{ 0x0F, 0x00, 0x00 },{ 0x0F, 0x00, 0xF0 },{ 0x0F, 0x0F, 0x00 },{ 0x0F, 0x0F, 0xF0 },{ 0x0F, 0xF0, 0x00 },{ 0x0F, 0xF0, 0xF0 },{ 0x0F, 0xFF, 0x00 },{ 0x0F, 0xFF, 0xF0 },{ 0xF0, 0x00, 0x00 },{ 0xF0, 0x00, 0xF0 },{ 0xF0, 0x0F, 0x00 },{ 0xF0, 0x0F, 0xF0 },{ 0xF0, 0xF0, 0x00 },{ 0xF0, 0xF0, 0xF0 },{ 0xF0, 0xFF, 0x00 },{ 0xF0, 0xFF, 0xF0 },{ 0xFF, 0x00, 0x00 },{ 0xFF, 0x00, 0xF0 },{ 0xFF, 0x0F, 0x00 },{ 0xFF, 0x0F, 0xF0 },{ 0xFF, 0xF0, 0x00 },{ 0xFF, 0xF0, 0xF0 },{ 0xFF, 0xFF, 0x00 },{ 0xFF, 0xFF, 0xF0 }};// A 256x5 pixel sprite (128x5 bytes) is used to draw the annunciators by copying rectangular areas into the OLED buffer.const uint8_t Sprites ={{ 0x00,0x00,0x00,0xF0,0xF0,0xF0,0x00,0x00,0x00,0xF0,0xFF,0xF0,0x0F,0x00,0x00,0x0F,0x00,0xF0,0xF0,0xFF,0xF0,0xF0,0x00,0xF0,0x00,0xF0,0x0F,0xFF,0x00,0xF0,0x0F,0x0F,0x0F,0x0F,0x00,0xF0,0x00,0x0F,0xFF,0x00,0xFF,0xF0,0x00,0xF0,0x00,0xF0,0x0F,0x00,0xFF,0xF0,0x00,0x0F,0xF0,0x00,0xFF,0xFF,0x00,0x0F,0xFF,0x0F,0xF0,0x0F,0xF0,0x00,0x0F,0x0F,0x00,0xF0,0xFF,0xF0,0xF0,0x00,0xFF,0x0F,0xF0,0x00,0xF0,0x00,0xFF,0x00,0xFF,0x00,0xF0,0x0F,0xF0,0x0F,0xFF,0x0F,0x00,0xF0,0xFF,0xF0,0x0F,0x00,0xF0,0x00,0x00,0xFF,0xF0,0x0F,0xF0,0x0F,0xFF,0x0F,0x00,0x0F,0x00,0xFF,0xF0,0xF0,0x0F,0x0F,0x00,0x00,0xF0,0xFF,0xF0,0xF0,0x0F,0x00,0x0F,0xFF,0x0F,0xF0,0x0F,0xFF,0x00,0x00 },{ 0x00,0x00,0x00,0x0F,0xFF,0x00,0x00,0x00,0x00,0xF0,0xF0,0x0F,0x0F,0x00,0x00,0xF0,0xF0,0xF0,0xF0,0x0F,0x0F,0x0F,0x00,0xF0,0x0F,0x0F,0x0F,0x0F,0x00,0xFF,0x0F,0x0F,0x0F,0x0F,0x00,0xF0,0x00,0x0F,0x00,0xF0,0xF0,0x00,0x00,0xFF,0x0F,0xF0,0xF0,0xF0,0x0F,0x00,0x00,0xF0,0x0F,0x00,0x00,0x0F,0x00,0x0F,0x00,0x0F,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0xF0,0xF0,0xF0,0x0F,0x0F,0x00,0xF0,0x0F,0x0F,0x0F,0x0F,0x00,0xF0,0xF0,0xF0,0x0F,0x0F,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F,0x00,0x0F,0x00,0x00,0x0F,0x0F,0x0F,0x00,0x0F,0xF0,0xFF,0x00,0x0F,0x00,0xF0,0x0F,0x0F,0x00,0x00,0xF0,0x0F,0x00,0xFF,0x0F,0x00,0x0F,0x00,0x0F,0x0F,0x0F,0x0F,0x00,0x00 },{ 0x00,0x00,0x0F,0xFF,0x0F,0xFF,0x00,0x00,0x00,0xF0,0xF0,0x0F,0x0F,0x00,0x00,0xFF,0xF0,0xF0,0xF0,0x0F,0x0F,0x0F,0x00,0xF0,0x0F,0x0F,0x0F,0xFF,0x00,0xF0,0xFF,0x0F,0x0F,0x0F,0x00,0xF0,0x00,0x0F,0x00,0xF0,0xFF,0x00,0x00,0xF0,0xF0,0xF0,0xFF,0xF0,0x0F,0x00,0x00,0xFF,0xFF,0x00,0x00,0xF0,0x00,0x0F,0xF0,0x0F,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F,0xF0,0xFF,0x0F,0x0F,0x00,0xFF,0x0F,0x0F,0x0F,0x0F,0x00,0xF0,0xF0,0xFF,0x0F,0xFF,0x0F,0x0F,0x0F,0xFF,0x0F,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0xF0,0x0F,0x0F,0x0F,0xF0,0x0F,0x0F,0x0F,0x00,0x0F,0x00,0xF0,0x0F,0xF0,0x00,0x00,0xF0,0x0F,0x00,0xF0,0xFF,0x00,0x0F,0xFF,0x0F,0x0F,0x0F,0x0F,0x00,0x00 },{ 0x00,0x00,0x00,0x0F,0xFF,0x00,0x00,0x00,0x00,0xF0,0xF0,0x0F,0x0F,0x00,0x00,0xF0,0xF0,0xF0,0xF0,0x0F,0x0F,0x0F,0x00,0xF0,0x0F,0x0F,0x0F,0x00,0x00,0xF0,0x0F,0x0F,0x0F,0x0F,0x00,0xF0,0x00,0x0F,0x00,0xF0,0xF0,0x00,0x00,0xF0,0x00,0xF0,0xF0,0xF0,0x0F,0x00,0x00,0xF0,0x0F,0x00,0x0F,0x00,0x00,0x0F,0x00,0x0F,0xF0,0x0F,0xF0,0x00,0x0F,0x0F,0x00,0xF0,0xF0,0x0F,0x0F,0x00,0xF0,0x0F,0xF0,0x0F,0x0F,0x00,0xFF,0x00,0xF0,0x0F,0x0F,0x0F,0xF0,0x00,0x0F,0x0F,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F,0x00,0x0F,0x00,0xF0,0x0F,0xF0,0x0F,0x00,0x0F,0x00,0x0F,0x00,0x0F,0x00,0xF0,0x0F,0x0F,0x00,0x00,0xF0,0x0F,0x00,0xF0,0x0F,0x00,0x00,0x0F,0x0F,0xF0,0x0F,0x0F,0x00,0x00 },{ 0x00,0x00,0x00,0xF0,0xF0,0xF0,0x00,0x00,0x00,0xF0,0xFF,0xF0,0x0F,0xFF,0x00,0xF0,0xF0,0xFF,0xF0,0x0F,0x00,0xF0,0x00,0xFF,0xF0,0xF0,0x0F,0x00,0x00,0xF0,0x0F,0x0F,0xFF,0x0F,0xF0,0xFF,0x00,0x0F,0xFF,0x00,0xF0,0x00,0x00,0xF0,0x00,0xF0,0xF0,0xF0,0x0F,0x00,0x00,0xF0,0x0F,0x00,0xFF,0xFF,0x00,0x0F,0xFF,0x0F,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x00,0xF0,0xF0,0x00,0xF0,0x00,0xF0,0x0F,0x0F,0x00,0xF0,0x00,0xF0,0xF0,0xFF,0x0F,0x0F,0x0F,0x0F,0x0F,0xFF,0x0F,0xF0,0xF0,0x0F,0x00,0x0F,0xF0,0xF0,0x00,0x00,0xFF,0xF0,0x0F,0x0F,0x0F,0xFF,0x0F,0x00,0x0F,0x00,0x0F,0x00,0xFF,0x0F,0x0F,0x00,0x00,0xFF,0x0F,0x00,0xF0,0x0F,0x00,0x0F,0xFF,0x0F,0x0F,0x0F,0xF0,0xF0,0x00 } };// Declare bytes array for a OLED frame buffer.// Dimensions are divided by 2 because one byte contains two 4-bit grayscale pixelsuint8_t tx_buffer[64 * 256 / 2];// Flag indicating finish of SPI transmission to OLEDvolatile uint8_t SPI1_TX_completed_flag = 1;// Flag indicating finish of SPI start-up initializationvolatile uint8_t Init_Completed_flag = 0;/* Private function prototypes -----------------------------------------------*/void SystemClock_Config(void);//******************************************************************************// Buffer to store the converted string representation of the main display line//char main_display_line[CHAR_COUNT + 1]; // +1 for null terminatorstatic char main_display_line[CHAR_COUNT + 1]; // Static ensures scope is global within the file//SPI transmission finished interrupt callbackvoid HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi){if (hspi->Instance == SPI1){SPI1_TX_completed_flag = 1;}}//******************************************************************************static uint8_t InverseByte(uint8_t a){a = ((a & 0x55) << 1) | ((a & 0xAA) >> 1);a = ((a & 0x33) << 2) | ((a & 0xCC) >> 2);return (a >> 4) | (a << 4);}//******************************************************************************// Function to map character bitmaps to ASCII characterstypedef struct {uint8_t bitmap; // 7 bytes for 5x7 character bitmapschar ascii; // Corresponding ASCII character} BitmapChar;// Font data: 96 characters, 7 bytes per character (each row)const BitmapChar bitmap_characters[] = {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ' '}, // Space{{0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x04}, '!'}, // 0x21, !{{0x09, 0x09, 0x12, 0x00, 0x00, 0x00, 0x00}, '"'}, // 0x22, "{{0x0A, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x0A}, '#'}, // 0x23, #{{0x04, 0x0F, 0x14, 0x0E, 0x05, 0x1E, 0x04}, '$'}, // 0x24, ${{0x19, 0x19, 0x02, 0x04, 0x08, 0x13, 0x13}, '%'}, // 0x25, %{{0x04, 0x0A, 0x0A, 0x0A, 0x15, 0x12, 0x0D}, '&'}, // 0x26, &{{0x04, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00}, '\''}, // 0x27, '{{0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02}, '('}, // 0x28, ({{0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08}, ')'}, // 0x29, ){{0x04, 0x15, 0x0E, 0x1F, 0x0E, 0x15, 0x04}, '*'}, // 0x2A, *{{0x00, 0x04, 0x04, 0x1F, 0x04, 0x04, 0x00}, '+'}, // 0x2B, +{{0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x08}, ','}, // 0x2C, ,{{0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00}, '-'}, // 0x2D, -{{0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C}, '.'}, // 0x2E, .{{0x01, 0x01, 0x02, 0x04, 0x08, 0x10, 0x10}, '/'}, // 0x2F, /{{0x0E, 0x11, 0x13, 0x15, 0x19, 0x11, 0x0E}, '0'}, // 0x30, 0{{0x04, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x0E}, '1'}, // 0x31, 1{{0x0E, 0x11, 0x01, 0x02, 0x04, 0x08, 0x1F}, '2'}, // 0x32, 2{{0x1F, 0x02, 0x04, 0x02, 0x01, 0x11, 0x0E}, '3'}, // 0x33, 3{{0x02, 0x06, 0x0A, 0x12, 0x1F, 0x02, 0x02}, '4'}, // 0x34, 4{{0x1F, 0x10, 0x1E, 0x01, 0x01, 0x11, 0x0E}, '5'}, // 0x35, 5{{0x06, 0x08, 0x10, 0x1E, 0x11, 0x11, 0x0E}, '6'}, // 0x36, 6{{0x1F, 0x01, 0x02, 0x04, 0x08, 0x08, 0x08}, '7'}, // 0x37, 7{{0x0E, 0x11, 0x11, 0x0E, 0x11, 0x11, 0x0E}, '8'}, // 0x38, 8{{0x0E, 0x11, 0x11, 0x0F, 0x01, 0x02, 0x0C}, '9'}, // 0x39, 9{{0x00, 0x0C, 0x0C, 0x00, 0x0C, 0x0C, 0x00}, ':'}, // 0x3A, :{{0x00, 0x0C, 0x0C, 0x00, 0x0C, 0x04, 0x08}, ';'}, // 0x3B, ;{{0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02}, '<'}, // 0x3C, <{{0x00, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x00}, '='}, // 0x3D, ={{0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08}, '>'}, // 0x3E, >{{0x0E, 0x11, 0x01, 0x02, 0x04, 0x00, 0x04}, '?'}, // 0x3F, ?{{0x0E, 0x11, 0x17, 0x15, 0x17, 0x10, 0x0F}, '@'}, // 0x40, @{{0x04, 0x0A, 0x11, 0x11, 0x1F, 0x11, 0x11}, 'A'}, // 0x41, A{{0x1E, 0x11, 0x11, 0x1E, 0x11, 0x11, 0x1E}, 'B'}, // 0x42, B{{0x0E, 0x11, 0x10, 0x10, 0x10, 0x11, 0x0E}, 'C'}, // 0x43, C{{0x1C, 0x12, 0x11, 0x11, 0x11, 0x12, 0x1C}, 'D'}, // 0x44, D{{0x1F, 0x10, 0x10, 0x1C, 0x10, 0x10, 0x1F}, 'E'}, // 0x45, E{{0x1F, 0x10, 0x10, 0x1F, 0x10, 0x10, 0x10}, 'F'}, // 0x46, F{{0x0E, 0x11, 0x10, 0x10, 0x13, 0x11, 0x0F}, 'G'}, // 0x47, G{{0x11, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11}, 'H'}, // 0x48, H{{0x0E, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0E}, 'I'}, // 0x49, I{{0x02, 0x04, 0x04, 0x04, 0x04, 0x04, 0x02}, 'J'}, // 0x4A, J{{0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11}, 'K'}, // 0x4B, K{{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F}, 'L'}, // 0x4C, L{{0x11, 0x1B, 0x1F, 0x1F, 0x11, 0x11, 0x11}, 'M'}, // 0x4D, M{{0x11, 0x1B, 0x1F, 0x1F, 0x1B, 0x11, 0x11}, 'N'}, // 0x4E, N{{0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E}, 'O'}, // 0x4F, O{{0x1E, 0x11, 0x11, 0x1E, 0x10, 0x10, 0x10}, 'P'}, // 0x50, P{{0x0E, 0x11, 0x11, 0x11, 0x11, 0x13, 0x0E}, 'Q'}, // 0x51, Q{{0x1E, 0x11, 0x11, 0x1E, 0x14, 0x12, 0x11}, 'R'}, // 0x52, R{{0x0E, 0x11, 0x10, 0x0E, 0x01, 0x11, 0x0E}, 'S'}, // 0x53, S{{0x1F, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, 'T'}, // 0x54, T{{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E}, 'U'}, // 0x55, U{{0x11, 0x11, 0x11, 0x11, 0x11, 0x0A, 0x04}, 'V'}, // 0x56, V{{0x11, 0x11, 0x1F, 0x1F, 0x1F, 0x11, 0x11}, 'W'}, // 0x57, W{{0x11, 0x11, 0x0A, 0x04, 0x04, 0x0A, 0x11}, 'X'}, // 0x58, X{{0x11, 0x11, 0x11, 0x0A, 0x04, 0x04, 0x04}, 'Y'}, // 0x59, Y{{0x1F, 0x01, 0x02, 0x04, 0x08, 0x10, 0x1F}, 'Z'}, // 0x5A, Z{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, '['}, // 0x5B, [{{0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04}, '\\'}, // 0x5C, \{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ']'}, // 0x5D, ]{{0x00, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01}, '^'}, // 0x5E, ^{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F}, '_'}, // 0x5F, _{{0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00}, '`'}, // 0x60, `{{0x00, 0x00, 0x0E, 0x01, 0x0F, 0x11, 0x0F}, 'a'}, // 0x61, a{{0x10, 0x10, 0x16, 0x19, 0x11, 0x11, 0x0E}, 'b'}, // 0x62, b{{0x00, 0x00, 0x0E, 0x10, 0x10, 0x10, 0x0E}, 'c'}, // 0x63, c{{0x01, 0x01, 0x0D, 0x13, 0x11, 0x11, 0x0E}, 'd'}, // 0x64, d{{0x00, 0x00, 0x0E, 0x11, 0x1F, 0x10, 0x0F}, 'e'}, // 0x65, e{{0x06, 0x09, 0x08, 0x1C, 0x08, 0x08, 0x08}, 'f'}, // 0x66, f{{0x00, 0x00, 0x0F, 0x11, 0x0F, 0x01, 0x1F}, 'g'}, // 0x67, g{{0x10, 0x10, 0x16, 0x19, 0x11, 0x11, 0x11}, 'h'}, // 0x68, h{{0x08, 0x00, 0x08, 0x18, 0x08, 0x08, 0x1C}, 'i'}, // 0x69, i{{0x02, 0x00, 0x06, 0x02, 0x02, 0x12, 0x0C}, 'j'}, // 0x6A, j{{0x10, 0x10, 0x12, 0x14, 0x18, 0x14, 0x12}, 'k'}, // 0x6B, k{{0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C}, 'l'}, // 0x6C, l{{0x00, 0x00, 0x1A, 0x15, 0x15, 0x15, 0x15}, 'm'}, // 0x6D, m{{0x00, 0x00, 0x16, 0x19, 0x11, 0x11, 0x11}, 'n'}, // 0x6E, n{{0x00, 0x00, 0x0E, 0x11, 0x11, 0x11, 0x0E}, 'o'}, // 0x6F, o{{0x00, 0x00, 0x1E, 0x11, 0x1E, 0x10, 0x10}, 'p'}, // 0x70, p{{0x00, 0x00, 0x0D, 0x13, 0x0F, 0x01, 0x01}, 'q'}, // 0x71, q{{0x00, 0x00, 0x16, 0x19, 0x10, 0x10, 0x10}, 'r'}, // 0x72, r{{0x00, 0x00, 0x0E, 0x10, 0x0E, 0x01, 0x1E}, 's'}, // 0x73, s{{0x08, 0x08, 0x1C, 0x08, 0x08, 0x09, 0x06}, 't'}, // 0x74, t{{0x00, 0x00, 0x11, 0x11, 0x11, 0x13, 0x0D}, 'u'}, // 0x75, u{{0x00, 0x00, 0x11, 0x11, 0x11, 0x0A, 0x04}, 'v'}, // 0x76, v{{0x00, 0x00, 0x11, 0x11, 0x15, 0x15, 0x0A}, 'w'}, // 0x77, w{{0x00, 0x00, 0x11, 0x0A, 0x04, 0x0A, 0x11}, 'x'}, // 0x78, x{{0x00, 0x00, 0x11, 0x11, 0x0F, 0x01, 0x0E}, 'y'}, // 0x79, y{{0x00, 0x00, 0x1F, 0x02, 0x04, 0x08, 0x1F}, 'z'}, // 0x7A, z{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, '{'}, // 0x7B, {{{0x01, 0x02, 0x04, 0x00, 0x04, 0x02, 0x01}, '|'}, // 0x7C, |{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, '}'}, // 0x7D, }{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, '~'}, // 0x7E, ~};// Convert a 5x7 bitmap to an ASCII character// The bitmap (7 rows of 5 bits each) is compared row by row against the font_data.// The comparison involves the 7 rows of the bitmap against the corresponding 7 rows in each font_data entry.char BitmapToChar(const uint8_t *bitmap) {// Iterate over the bitmap_characters arrayfor (int i = 0; i < sizeof(bitmap_characters) / sizeof(BitmapChar); i++) {// Compare the input bitmap with the current character's bitmapif (memcmp(bitmap, bitmap_characters.bitmap, FONT_HEIGHT) == 0) {return bitmap_characters.ascii; // Return the matching ASCII character}}// If no match is found, return '?'return '?';}//******************************************************************************// Each character on the display is encoded by a matrix of 40 bits packed// into 5 consecutive bytes. 5x7=35 bits (S1-S35) define the pixel image of the character,// 1 bit (S36) is the annunciator, 4 bits are not used. To optimize VFD PCB routing,// the bit order in packets is shuffled://// S17 S16 S15 S14 S13 S12 S11 S10// S9 S8 S7 S6 S5 S4 S3 S2// S1 S36 0 0 0 0 S35 S34// S33 S32 S31 S30 S29 S28 S27 S26// S25 S24 S23 S22 S21 S20 S19 S18//// The Packets_to_chars function sorts the character bitmap, extracts the annunciator// flag, and stores the result in separate arrays chars[][] and flags[]//// 0 0 0 S1 S2 S3 S4 S5// 0 0 0 S6 S7 S8 S9 S10// 0 0 0 S11 S12 S13 S14 S15// 0 0 0 S16 S17 S18 S19 S20// 0 0 0 S21 S22 S23 S24 S25// 0 0 0 S26 S27 S28 S29 S30// 0 0 0 S31 S32 S33 S34 S35//void Packets_to_chars(void){for (int i = 0; i < PACKET_COUNT; i++) {uint8_t d0 = rx_buffer[i * PACKET_WIDTH + 0];uint8_t d1 = rx_buffer[i * PACKET_WIDTH + 1];uint8_t d2 = rx_buffer[i * PACKET_WIDTH + 2];uint8_t d3 = rx_buffer[i * PACKET_WIDTH + 3];uint8_t d4 = rx_buffer[i * PACKET_WIDTH + 4];chars[Reorder] = 0x1F & InverseByte((d1 << 4) | ((d2 & 0x80) >> 4));chars[Reorder] = 0x1F & InverseByte((d0 << 7) | ((d1 & 0xF0) >> 1));chars[Reorder] = 0x1F & InverseByte((d0 & 0xFE) << 2);chars[Reorder] = 0x1F & InverseByte(((d0 & 0xC0) >> 3) | (d4 << 5));chars[Reorder] = 0x1F & InverseByte(d4 & 0xF8);chars[Reorder] = 0x1F & InverseByte(d3 << 3);chars[Reorder] = 0x1F & InverseByte((d2 << 6) | ((d3 & 0xE0) >> 2));flags[Reorder] = (d2 & 0x40) == 0x40;// Update annunciator boolean array for MAIN annunciators (G1 to G18)if (i < 18) {Annunciators = flags[Reorder];}}// Null-terminate the main display line stringmain_display_line = '\0';}void ReorderAnnunciators(void) {// Map Annunciators[] to AnnunciatorsReordered[] for left-to-right order.AnnunciatorsReordered = Annunciators; // G1AnnunciatorsReordered = Annunciators; // G2AnnunciatorsReordered = Annunciators; // G3AnnunciatorsReordered = Annunciators; // G4AnnunciatorsReordered = Annunciators; // G5AnnunciatorsReordered = Annunciators; // G6AnnunciatorsReordered = Annunciators; // G7AnnunciatorsReordered = Annunciators; // G8AnnunciatorsReordered = Annunciators; // G9AnnunciatorsReordered = Annunciators; // G10AnnunciatorsReordered = Annunciators; // G11AnnunciatorsReordered = Annunciators; // G12AnnunciatorsReordered = Annunciators; // G13AnnunciatorsReordered = Annunciators; // G14AnnunciatorsReordered = Annunciators; // G15AnnunciatorsReordered = Annunciators; // G16AnnunciatorsReordered = Annunciators; // G17AnnunciatorsReordered = Annunciators; // G18}void Main_Aux_TFT_Display(void) {// Clear LCD buffersmemset(LCD_buffer_packets, 0, sizeof(LCD_buffer_packets));memset(LCD_buffer_bitmaps, 0, sizeof(LCD_buffer_bitmaps));memset(LCD_buffer_chars, 0, sizeof(LCD_buffer_chars));ReorderAnnunciators(); // re-order the annunciators so Annunnciator is above G1char annunciator_debug = "Annunciators: "; // Buffer for annunciator state debugfor (int i = 0; i <= 17; i++) { // G1 to G18// Use already-decoded data from Packets_to_charsuint8_t *bitmap = chars; // Get the bitmap for this characterchar ascii_char = BitmapToChar(bitmap); // Convert bitmap to ASCII character// MAIN Update individual variablesif (i == 0) G1 = ascii_char;else if (i == 1) G2 = ascii_char;else if (i == 2) G3 = ascii_char;else if (i == 3) G4 = ascii_char;else if (i == 4) G5 = ascii_char;else if (i == 5) G6 = ascii_char;else if (i == 6) G7 = ascii_char;else if (i == 7) G8 = ascii_char;else if (i == 8) G9 = ascii_char;else if (i == 9) G10 = ascii_char;else if (i == 10) G11 = ascii_char;else if (i == 11) G12 = ascii_char;else if (i == 12) G13 = ascii_char;else if (i == 13) G14 = ascii_char;else if (i == 14) G15 = ascii_char;else if (i == 15) G16 = ascii_char;else if (i == 16) G17 = ascii_char;else if (i == 17) G18 = ascii_char;// Append MAIN to debug buffers for additional debuggingsnprintf(LCD_buffer_bitmaps + strlen(LCD_buffer_bitmaps),sizeof(LCD_buffer_bitmaps) - strlen(LCD_buffer_bitmaps),"%d : [%02X, %02X, %02X, %02X, %02X, %02X, %02X]\n",i, bitmap, bitmap, bitmap, bitmap,bitmap, bitmap, bitmap);// Append annunciator states to debug stringsnprintf(annunciator_debug + strlen(annunciator_debug),sizeof(annunciator_debug) - strlen(annunciator_debug),"G%d=%s ", i + 1, Annunciators ? "ON" : "OFF");}// Null-terminate the Main display debug stringmain_display_debug = '\0';for (int i = 18; i <= 46; i++) { // G19 to G47// Use already-decoded data from Packets_to_charsuint8_t *bitmap = chars; // Get the bitmap for this characterchar ascii_char = BitmapToChar(bitmap); // Convert bitmap to ASCII character// AUX Update individual variablesif (i == 18) G19 = ascii_char;else if (i == 19) G20 = ascii_char;else if (i == 20) G21 = ascii_char;else if (i == 21) G22 = ascii_char;else if (i == 22) G23 = ascii_char;else if (i == 23) G24 = ascii_char;else if (i == 24) G25 = ascii_char;else if (i == 25) G26 = ascii_char;else if (i == 26) G27 = ascii_char;else if (i == 27) G28 = ascii_char;else if (i == 28) G29 = ascii_char;else if (i == 29) G30 = ascii_char;else if (i == 30) G31 = ascii_char;else if (i == 31) G32 = ascii_char;else if (i == 32) G33 = ascii_char;else if (i == 33) G34 = ascii_char;else if (i == 34) G35 = ascii_char;else if (i == 35) G36 = ascii_char;else if (i == 36) G37 = ascii_char;else if (i == 37) G38 = ascii_char;else if (i == 38) G39 = ascii_char;else if (i == 39) G40 = ascii_char;else if (i == 40) G41 = ascii_char;else if (i == 41) G42 = ascii_char;else if (i == 42) G43 = ascii_char;else if (i == 43) G44 = ascii_char;else if (i == 44) G45 = ascii_char;else if (i == 45) G46 = ascii_char;else if (i == 46) G47 = ascii_char;// Append AUX to debug buffers for additional debuggingsnprintf(LCD_buffer_bitmaps + strlen(LCD_buffer_bitmaps),sizeof(LCD_buffer_bitmaps) - strlen(LCD_buffer_bitmaps),"%d : [%02X, %02X, %02X, %02X, %02X, %02X, %02X]\n",i, bitmap, bitmap, bitmap, bitmap,bitmap, bitmap, bitmap);}// Null-terminate the Aux display debug stringmain_display_debug = '\0';}//************************************************************************************************************************************************************// Mainint main(void){// MCU Configuration--------------------------------------------------------// Reset of all peripherals, Initializes the Flash interface and the Systick.HAL_Init();// Configure the system clockSystemClock_Config();// Initialize all configured peripheralsMX_GPIO_Init();MX_DMA_Init();MX_SPI1_Init();MX_SPI2_Init();/* Infinite loop */SSD1322_API_init();Init_Completed_flag = 1; // Now is a safe time to enable the EXTI interrupt handlerset_buffer_size(256, 64); // SSD1322 OLED sizewhile (1){Packets_to_chars();Main_Aux_TFT_Display();fill_buffer(tx_buffer, 0); // Clearing OLED frame buffer// Drawing (recoding, horizontal and vertical scaling) of the characters of the main display linefor (int i = 0; i < CHAR_HEIGHT; i++)for (int j = 0; j < LINE1_LEN; j++)for (int k = 0; k < 5; k++)tx_buffer[2 + j * 7 + k + (LINE1_Y + i * 5 + 0) * 128] = tx_buffer[2 + j * 7 + k + (LINE1_Y + i * 5 + 1) * 128] =tx_buffer[2 + j * 7 + k + (LINE1_Y + i * 5 + 2) * 128] = tx_buffer[2 + j * 7 + k + (LINE1_Y + i * 5 + 3) * 128] = Upscale1[chars];// Drawing (recoding and vertical scaling) of the characters of the auxiliary display line.for (int i = 0; i < CHAR_HEIGHT; i++)for (int j = 0; j < LINE2_LEN; j++)for (int k = 0; k < 3; k++)tx_buffer[7 + j * 4 + k + (LINE2_Y + i * 2 + 0) * 128] = tx_buffer[7 + j * 4 + k + (LINE2_Y + i * 2 + 1) * 128] = Upscale2[chars[j + LINE1_LEN]];// Drawing of the annunciatorsfor (int k = 0; k < LINE1_LEN; k++)if (flags)for (int i = 0; i < 5; i++)for (int j = 0; j < 7; j++)tx_buffer[1 + j + k * 7 + i * 128] = Sprites[1 + k * 7 + j];send_buffer_to_OLED(tx_buffer, 0, 0); // Send the frame buffer content to OLEDHAL_GPIO_TogglePin(GPIOC, TEST_OUT_Pin); // Test LED toggle};}// System Clock Configurationvoid SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };//Initializes the RCC Oscillators according to the specified parameters in the RCC_OscInitTypeDef structure.RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}// Initializes the CPU, AHB and APB buses clocksRCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}}// This function is executed in case of error occurrence.void Error_Handler(void){// User can add his own implementation to report the HAL error return state__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */}#ifdef USE_FULL_ASSERT/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/void assert_failed(uint8_t *file, uint32_t line){/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */}#endif /* USE_FULL_ASSERT */

author: Mickle T.
author_rank: Frequent Contributor
timestamp: November 17, 2024, 02:37:44 pm
content: Ian, thanks for the MAIN.C source code. I'm not a software programmer either, but it's never too late to learnAFAIK, the Advantest display module uses the second half of the ASCII table to store special characters. In DIAG mode, characters with codes 0xE0...0xE8 are displayed on the display to simulate vertical and horizontal fill.

author: dietert1
author_rank: Super Contributor
timestamp: November 17, 2024, 04:34:27 pm
content: You can find very efficient code for all this in the archive i posted above (file: inData_Format.c). Except i used int64 (8 bytes per image). There is a character table for most of the characters i saw during data taking and configuration and there is an optimized binary search to do the OCR.In the end i finished without fully implementing a higher resolution font as i knew that characters would be missing, e.g. those graphics characters that are now mentioned by Mickle T. One might also follow a hybrid approach, like replacing known character images by higher resolution ones while leaving unknown characters as they are. The STM32H730 MCU i selected has enough free flash for a very nice and complete font, even with anti-aliasing.Regards, Dieter

author: IanJ
author_rank: Unknown
timestamp: November 17, 2024, 05:29:14 pm
content: Quote from: dietert1 on November 17, 2024, 04:34:27 pmThanks, I grabbed a few of the hex character fonts (some lower case and symbols) that I hadn't verified yet and converted them to my format.Cheers,Ian.

author: dietert1
author_rank: Super Contributor
timestamp: November 17, 2024, 06:04:54 pm
content: By the way, my project outputs OCR'd display data via the debug uart (Uart1 meant to be connected via STLink).Regards, Dieter

author: vinovino
author_rank: Contributor
timestamp: November 21, 2024, 02:26:37 am
content: Can this VFD replacement work on Advantest R6243 display?

author: daisizhou
author_rank: Super Contributor
timestamp: November 21, 2024, 02:54:26 am
content: I also encountered the same fault as you, that is, the display is dim due to the aging of the VFD.I don't know what is the best solution for my VFD GU256X32-302.GU256X32-302 has been discontinued.The interface positions of GU256X32-800 and GU256X32-820 are different. I don't know if they are compatible.I would be very grateful for your help, thank you

author: Mickle T.
author_rank: Frequent Contributor
timestamp: November 21, 2024, 05:06:32 am
content: Quote from: vinovino on November 21, 2024, 02:26:37 amIt can be easily adapted to the R6243 display. It is only necessary to adjust the segment arrangement table and the regeneration sequence table. I think I will do this as soon as I get hold of such a power supply.

author: gamalot
author_rank: Super Contributor
timestamp: November 24, 2024, 10:47:55 am
content: I am also trying to do almost the same thing as dietert1 did, but it got delayed for some reason. I chose the STM32H750VBT6 because it is much cheaper than the STM32H730VBT6 if purchased from LCSC.I have only done a small part - displaying some pictures on the screen, which I think is a good start. Recognizing those characters should be easy, so presenting in different themes should be an option.I haven't looked at the manual yet, and don't know if the tR6581 can display customized content like some other instruments, if it can, special pattern character sequences can be recognized as some instructions to control the display to do anything it can do, such as changing the theme, adjusting the backlight brightness, running screensavers, etc.I ordered a 6-layer board with a size of 50mmx50mm, which has some other functions on it, USB, battery for the real-time clock, lithium battery charging, temperature and humidity sensor, buttons, etc. Please just ignore them.

author: Mickle T.
author_rank: Frequent Contributor
timestamp: November 24, 2024, 11:33:52 am
content: Quote from: gamalot on November 24, 2024, 10:47:55 amWithout a firmware patch R6581 can't display customized content like some other DMM. The R6581 supports the command "DISPLAY 0" which prints the string "DISPLAY OFF" to the display. Recognition of this string can be used as a flag to turn off the display backlight.

author: gamalot
author_rank: Super Contributor
timestamp: November 24, 2024, 11:50:49 am
content: Quote from: Mickle T. on November 24, 2024, 11:33:52 amThis is bad news, but being able to send a command to turn off the backlight is good enough, better than the switch I put in the PCMCIA slot on the front panel to turn off the VFD.I also considered long-pressing a button to turn off or wake the display, and the Home button seemed like a good choice.

author: dietert1
author_rank: Super Contributor
timestamp: November 24, 2024, 12:05:34 pm
content: In my project (see archive posted above) character recognition is implemented and the "DISPLAY OFF" message that appears after the "Display Off" GPIB command turns off the TFT backlight.My board was designed for that purpose with its size matching the size of the TFT, so it "disappears" when mounting the TFT on those brackets i showed above. The intention was reducing EMI, as all high frequency signals are covered by very close metal surfaces: The metal back of the TFT and the ground planes of the display board on one side and the ground plane of the R6581 front PCB on the other side, both with less than 3 mm distance.Regards, Dieter

author: gamalot
author_rank: Super Contributor
timestamp: November 24, 2024, 12:45:40 pm
content: Quote from: dietert1 on November 24, 2024, 12:05:34 pmWhat you are looking at is a multi-purpose PCB, which can be a replacement screen for R6581, an alarm clock with weather information, or a lithium battery charger. Every time I order PCBs from JLC, I only use one or two of them, and the rest are all wasted, so I decided to try to make them have different uses.I will remove the components that are not relevant to this project in the next version (if there is one), change the PCB size to the same height as the TFT display or even smaller, and shield them with copper foil tape if necessary (actually I don't think there will be EMI problems).

author: dietert1
author_rank: Super Contributor
timestamp: November 24, 2024, 01:57:00 pm
content: Yes, i understood that you designed your own board, too. I also saw a Adafruit board that drives the TFT, once more somewhat larger than mine. I tried to focus on getting the display replacement.Concerning EMI: My graphics board produces digital video at 21 MHz, while the original VFD probably multiplexes at two KHz or so. And once more i didn't want to study that in all detail, but find a good solution that doesn't add any negative impact on the 8.5 digit meter.Regards, Dieter

author: gamalot
author_rank: Super Contributor
timestamp: November 24, 2024, 08:07:29 pm
content: Quote from: dietert1 on November 24, 2024, 01:57:00 pmSpeaking of frequency, I found something strange. Mikle's circuit diagram marked the negative pulse width of CK4 as 2us, but I actually measured the frequency to be about 1MHz on my meter. Have you ever noticed the frequency of the clock signal on your R6581?

author: dietert1
author_rank: Super Contributor
timestamp: November 24, 2024, 09:17:54 pm
content: In my notes if found that the interrupt signal ("start of transmission") is a positive pulse of 4.73 usec every 9 msec.SPI clock is 1 MHz, 8 negative pulses every 12 usec. During the 4 usec pauses the clock idles high. The data signal changes its value with the falling edge of the clock.One packet of 5 bytes = 40 bits = 1 digit takes 184 usec in total.I estimated 9 msec => 110 Hz refresh rate, times 18 mux positions gives about 2 KHz. Except the lower line has more positions, so it may be more like 3 KHz.Regards, Dieter

author: IanJ
author_rank: Unknown
timestamp: November 25, 2024, 12:09:30 am
content: Quote from: gamalot on November 24, 2024, 10:47:55 amLooks to be the same 4.58" LCD as I am playing with.....320x960 pixels.I am working with the LT7680 board from buydisplay.com which takes the heavy lifting away from the BluePill.Downside is that's an extra Pcb, but it's no big deal to integrate onto my mounting arrangement I have in mind......everything within the footprint of the LCD itself.I'm developing on Visual Studio 2022 with VisualGDB plugin.I first got MickleT's original source ported over to Visual Studio, compiling and tested, then added conversion of the R6581 bitmap data to strings. G1 to G47 and the annunciators.Am now working to integrate the new LCD drive.....hmmm, the LT7680 datasheet could be better!A great wee project to work on......makes a change from repairs here in the home workshop.Ian.

author: gamalot
author_rank: Super Contributor
timestamp: November 26, 2024, 03:09:15 pm
content: Thank you Mickle T. Thank you everyone!Maybe I should do something fun next.

author: IanJ
author_rank: Unknown
timestamp: November 26, 2024, 05:50:29 pm
content: Quote from: gamalot on November 26, 2024, 03:09:15 pmAwesome gamalot!........I hope I am not too far behind you....:-)Ian.

author: IanJ
author_rank: Unknown
timestamp: November 30, 2024, 10:37:56 pm
content: Hi all,Here's my effort so far.....4.58", 320x960 TFT LCD.STM32 Blue Pill (STM32F103C8T6)LT7680A-R TFT Graphics Controller.It's been quite a journey to get to where this is right now, but today I got text rendering working on the display.......over the moon and over the technical hurdle, should be easy from now!I decided to use the STM32 Blue Pill as I am experienced with them and they are easily integrated for somebody wanting to build up my version. However, out of the box and on their own they are NOT up to the task. Not enough I/O for one.I picked the LT7680A-R controller because of it's size, it's narrower than the LCD and will mean it's easy to mount on the back and it of course took the heavy lifting away from the Blue Pill, just simple SPI comms with the LT7680A-R is required.However, the way the LT7680A-r works is that you still need to communicate directly (via the pcb) to the LCD's ST7701S COG, albeit only once at startup to configure things.In total I needed 3 SPI ports, the R6581T gets one, the LT7680A-R and............oh, the Blue Pill only has 2 SPI ports!So, I bit banged a 3rd, the 3-wire interface to the ST7701S. It's only used once at boot so no worries.Actually, I nearly went with the STM32 Black Pill (I still might) as it has 3 SPI ports, but we'll see.I plan to design a Pcb thats the same dimensions as the LCD and mount everything on it. The green Pcb in the photo is just a temporary one used for dev.Software is developed in Visual Studio/Visual GDB, and through the STLINKV3 it's got pretty good debugging, I can live watch variables etc.By far the biggest problem was the LT7680A-R, the datasheet/manual and the supporting App notes are quite extensive. I had to sync the settings such as the back porch stuff and of course they are in different units and needed tweaked even after that. Also, having to set up the LCD PCLK, VSYNC, HSYNC settings...........having never driven a TFT direct before it was quite a learning experience.The LCD pic below is just the first font I picked, plan is to have the nicest, smoothest font I think.Thats all for now.Ian.

author: gamalot
author_rank: Super Contributor
timestamp: December 01, 2024, 10:33:16 am
content: I tried to capture the dot pattern of all characters, but I only got 80 of them. There are a few characters that I have not been able to display on the screen, such as lowercase letters b, j, p, q, and left and right brackets.I attached the characters I found, each character takes 6 bytes, the first 5 are captured from the serial bus, and the last byte is the ascii value.I also tried to use different fonts to present them, maybe because of my lack of artistic cultivation, I am not satisfied with my work so far ...

author: IanJ
author_rank: Unknown
timestamp: December 01, 2024, 11:20:52 am
content: Quote from: gamalot on December 01, 2024, 10:33:16 amThanks, I know there are some characters I haven't mapped properly yet, certainly some of the alphabet, and those up/down arrows etc. MickleT also mentioned some special graphics under one of the menu's.Not sure if they and some others are available in the LT7680A-R character map sets, if not I'll have to create a few UDG's. The LT7680A-R has a flash rom on it that's available to upload to.A couple of limitations, one being there is a maximum font size of 32x32 in the LT7680A-R internal set, but it does allow a x2 to x4 multiplier on top of that for the size. Their way of reducing character map memory footprint I guess.So, I am using 16x32 with a x3 multiplier, you can see the jaggies on some of my characters.....................The pitfalls of such a hi-res LCD!Pic below of my progress today, live data now working. Hmmmm, wonder if it's worth putting the AUX line in a different colour!EDIT: Added another couple pics with Annunciators and different colours, taking my Keysight 34461A for some ideas. Green behind the R6581T panel looks too dim I think.This has been great fun so far......especially as I am no software engineer!Notes:TFT LCD Display refresh rate = 14.5HzUsed FLASH: 25KB out of 64KB (39%)Used SRAM: 3544 bytes out of 20KB (17%)Ian.

author: dietert1
author_rank: Super Contributor
timestamp: December 02, 2024, 03:49:29 pm
content: That looks nice, so higher resolution fonts may be worth it. I also went to white as the R6581 front bezel takes away quite some brightness and i wanted to stay with 20 mA backlight current.I also thought about using color, e.g. show the error anunciator or other error info in red.Or if the meter operates in the same range for some time, one could replace the range info by a running average including standard deviation. A real playground..Regards, Dieter

author: IanJ
author_rank: Unknown
timestamp: December 02, 2024, 09:26:40 pm
content: All,For some reason I found yellow has more punch through the R6581 bezel than white, not a lot in it mind you and maybe just my eyes.The OHMS symbol is testing me to the limit of my C coding ability.......The LT7680A-R only supports ISO 8859-1, 2, 4 & 5....and not an OHMS symbol in sight.It does support UCG - User defined Characted Sets - but the datasheet/manual/App note is pretty sketch in it's usage.I think I have my hex array stored properly, but calling it up for display brings up a blank.I swear it was a lot easier to do on the ZX Spectrum back in the day!I have a contact at Levetop Semiconductor, waiting on a reply, and hopefully some sample code.They have been great, offering assistance!It'll be nice to get the UCGs working, it will help with the E0 to E8 extended chars required for the DIAG screen vertical and horizontal fills.EDIT: Levetop sent me sample code for UCG’s…….great stuff!Ian.

author: IanJ
author_rank: Unknown
timestamp: December 04, 2024, 08:45:06 pm
content: Hi all,Managed to get the UCG user-defined characters working on the LT7680A-R IC per the attached.Small issue with the smaller one, so had to swap it out for the word 'ohm'......for now anyways.I can create any amount of UCGs and call them up as long as they are all the same size.......but defining 16x32 and 12x24 has proved problematic due to the way the LT7680A-R works.......as I see it.Another small issue is the line right along the bottom of the LCD (which actually won't show up behind the bezel), I can get rid of it by adjusting the display parameters, but it tends to make the display unstable in other ways.....so leaving it as it is. If I had access to the FULL spec of the TFT LCD then I could probably fix it but alas no full spec!UPDATE:I fixed the 2nd OHM symbol on the AUX line. Suggestion from Levetop, instead of rendering the UCGs at boot and using them individually, I am now rendering them on the fly just before they get used in the same area of memory. A little bit more of a CPU overhead for the Blue Pill but it seemed to handle it ok and the display is still fast.Ian.

author: IanJ
author_rank: Unknown
timestamp: December 05, 2024, 07:37:02 pm
content: Hi all,Enough software for now, all working including ohms symbol.Info:Lcd update rate in every mode except resistance = 20.4Hz.Lcd update rate in resistance modes = 14Hz.This is due to the on-the-fly uploading of the user defined ohms graphic (hex symbol data) to the LT7680A-R IC.I have also been working on a Pcb that will mount on the back of the display board and hold the LT7680A-R and Blue Pill board, keeping everything as low profile as possible.Resultant connections to be made are just the 5 wires to the R6581 display board to pick up +5Vdc and the 3 serial signals.Photos attached.EDIT:Re-mounted on back of display board (more room), much better mounting.EDIT2:Found issue with backlighting registers so have managed to increase brightness by about 10%+ over the photos below.EDIT3:My GitHub repo for this project:https://github.com/Ian-Johnston/R6581_VS_DisplayEDIT4:I have edited the character encoding on the ones I had missed on the DIAG screen, and have come up with my own idea for the animated DISPLAY test. That should now cover everything and thus no longer displaying "?" for any missing font data.Also added an option to tie input pin B0 down to 0V to swap the colours on the MAIN and AUX lines at boot. Default white for MAIN and yellow for AUX.https://youtube.com/shorts/ayPeOh1u92w?feature=shareIan.

author: IanJ
author_rank: Unknown
timestamp: December 11, 2024, 02:22:04 pm
content: Hi all,LT7680A-R TFT LCD Driver for the R6581 DMM, prototype Pcb fitted to my R6581T......finally!Photos below, and here's a quick YT Short:https://youtube.com/shorts/QG-DmSFydeg?feature=shareAlso, photo of what will be the production Pcb. Gerbers will be available soon in addition to the STM32 Blue Pill code etc.Just got to double check VFD SDA and SCK in-case I reversed them on the Pcb....oops!The code is 99.9% complete, most of the past couple of days was going through the Calibration menu's on the R6581 and making sure I had all the font characters mapped. I did have a bit of trouble with dual OHM symbols on the Cal menus but got it fixed in the end. If the LT7680A-R had a built in character for the OHM symbol it would have saved me 250 lines of C code manipulating the OHM symbols into place.There are two header links on the board:-LK1 = swap the MAIN and AUX line colours (yellow & white). I prefer white for MAIN.LK2 = choose between green or cyan for the ANNUNCIATOR colour. I prefer green.The board has a notch out it as you will see, that's to accommodate a 100uF electrolytic capacitor on the main display board that gets in the way. I didn't want to move it.After fitting the board there is just 5 short connections down to the R6581 main display board.Assembly of the whole thing is a little tight, due to the length of the LCD flat flex and the R6581 front panel flat flex's also, if you don't want to disconnect them.Note: The LT7680A-R board as purchased needs two solder links changed (to do with backlighting internal or external control):J1 = openJ2 = closedJ3 closed (as supplied)When the production PCBs arrive from PCBWAY I'll be doing a full YT video of the installation on my other R6581T.I'll also edit this post and put a full parts list along with the gerbers and code etc.Again, thanks to MickleT for the original reverse engineering without which........PS. Boot screen on the LCD has a wee 5sec nod to MickleT.Ian.

author: IanJ
author_rank: Unknown
timestamp: December 17, 2024, 02:10:00 pm
content: Hi all,Video published on my TFT LCD effort:https://youtu.be/rv6x6VsWyRoFiles:GIT source =https://github.com/Ian-Johnston/R6581_VS_DisplayGIT .HEX file =https://github.com/Ian-Johnston/R6581_VS_Display/tree/master/VisualGDB/DebugGerbers =https://www.ianjohnston.com/R6581_TFT/7680-Controller_backside5_V1_3.zipInstructions =https://www.ianjohnston.com/R6581_TFT/Instructions.pdfParts:LCD & LT7680A-R (c/w flat flex & FPC conn) =https://www.buydisplay.com/bar-type-4-58-inch-320x960-ips-tft-lcd-display-spi-rgb-interface1 x 33uF 100V electrolytic capacitor (optional)1 x 100uF 10V electrolytic capacitor1 x 1uF polyester capacitor2 x 10mm M3 brass standoffs1 x STM32 Blue Pill (STM32F103C8T6)1 x 5-way male SIL header2 x 20-way arduino style female header2 x Strips 2mm double sided tape1 x Strip 6mm single sided foamIan.

author: branadic
author_rank: Super Contributor
timestamp: December 17, 2024, 04:47:59 pm
content: Well done.What are the other color schemes that can be choosen?Now you only need to fix the INL issue.-branadic-

author: IanJ
author_rank: Unknown
timestamp: December 17, 2024, 05:17:11 pm
content: Quote from: branadic on December 17, 2024, 04:47:59 pmNothing heavy.......Swaps the yellow and white MAIN/AUX display colours.Select green or cyan for the Annunciators.The jumpers are read at boot.Ian.

author: branadic
author_rank: Super Contributor
timestamp: December 17, 2024, 05:33:23 pm
content: Thanks, a VFD like look instead of the Rigol color scheme would have been nice, but I also like the look of the Valhalla 2720 display.-branadic-

author: IanJ
author_rank: Unknown
timestamp: December 18, 2024, 08:24:05 am
content: Quote from: branadic on December 17, 2024, 05:33:23 pmI used the built in font on the LT7680A-R so very much restricted to that. However, unless I am wrong I think there is an option to load complete fonts to the flash IC on the pcb but I never looked at doing that at all.Ian

author: chekhov
author_rank: Regular Contributor
timestamp: December 18, 2024, 04:36:49 pm
content: I thought that you did created a new font for this IC.However if I remember correctly (because I was looking at this board when ordered this display) the biggest limitation is the font size that it can hold, so you won't be able to draw big digits.

author: branadic
author_rank: Super Contributor
timestamp: December 18, 2024, 06:21:30 pm
content: When I wrote "VFD like look" I meant color-wise, so more green/blue'ish instead of the Rigol color scheme with yellow, cyan and green.-branadic-

author: IanJ
author_rank: Unknown
timestamp: December 18, 2024, 07:54:38 pm
content: Quote from: chekhov on December 18, 2024, 04:36:49 pmThe biggest font is 32x32 pixels, but it supports multipliers on top of that to scale it up. I am using a 16x32 font and scaling that up which works out just right for the MAIN displayI only created a new character for the OHM symbol.Ian

author: IanJ
author_rank: Unknown
timestamp: December 18, 2024, 09:17:13 pm
content: Quote from: branadic on December 18, 2024, 06:21:30 pmAhh, ok.Due to the smoked window some colours don’t project enough even with the backlighting at full brightness, hence yellow/white seem best at least for the main row……in my eyes anyway.I’ll try and come up with a way to select further colours…….i guess ultimately the user could pick their own and save.Ian.

author: chekhov
author_rank: Regular Contributor
timestamp: December 18, 2024, 09:35:02 pm
content: Quote from: IanJ on December 18, 2024, 07:54:38 pmI must have missed that piece, thanks.Quote from: IanJ on December 18, 2024, 07:54:38 pmOh ... omega. Once I tried to create vector font for K2000/K2001, but something went wrong ...

author: IanJ
author_rank: Unknown
timestamp: December 24, 2024, 06:14:29 pm
content: Hi all,During my TFT upgrade I missed the conversion of a character on the R6581T display.......but no VFD or OLED to find out what it is supposed to be!I am thinking it's a right arrow?Per attached, can anyone with an VFD/OLED confirm?.........a photo would be great so I can analyze the pixel data.It's on the RECALL, MANUAL display.I was testing a PCMCIA memory card with the R6581T where I came upon it.Ian.

author: chekhov
author_rank: Regular Contributor
timestamp: December 24, 2024, 06:46:51 pm
content: If I found it right, manual shows ~(Searched 'recall', around 6 - 16, page 144)I see you have a few lines in character map filled with zeros, for [ ] { } and ~.Line for | (vertical line) also look strange - must be almost like !, but looks like >.

author: Mickle T.
author_rank: Frequent Contributor
timestamp: December 24, 2024, 07:14:17 pm
content: RECALL:

author: IanJ
author_rank: Unknown
timestamp: December 24, 2024, 07:51:33 pm
content: Thanks guys…….I kinda thought it was a character I hadn’t come across anywhere else in the menu system.UPDATE:Fixed and GIT is updated.UPDATE2:Upper case J symbol fixed.Also add code to send unmatched chars to Live Watch so they can be easily read and converted.UPDATE3:% symbol fixed.UPDATE4:Re-write AUX display including provision of OHM symbols up to4off5off per line.Ian.

author: IanJ
author_rank: Unknown
timestamp: December 25, 2024, 08:22:09 am
content: Anyone got a source of R6581 compatible PCMCIA cards?I have a working 1mb SRAM card, but it only shows up at around 60k free after initialize (integer overflow maybe?)…….plus it doesn’t have an integral battery.What’s the R6581 max size?All the Flash type cards I have don’t work or show up as a lot less than 60k.Presume the interface is PCMCIA II and not III.Ian

author: chekhov
author_rank: Regular Contributor
timestamp: December 26, 2024, 10:50:18 am
content: Quote from: IanJ on December 17, 2024, 02:10:00 pmBe aware that they only sell those LT7680A-R-based boards together with TFT displays, one for each, refused to sell separately.

author: IanJ
author_rank: Unknown
timestamp: December 27, 2024, 11:54:23 am
content: Quote from: chekhov on December 26, 2024, 10:50:18 amYes, I did email them also and ask if they could release the boards separately, but they declined...........I was wanting some spare.Luckily, it's quite an inexpensive kit considering.....PS. I have updated my source/.HEX on GIT, now handles more OHM symbols on the AUX line......I found one line where there are 5off them (CONFIGURE, 2W or 4W, RANGE-LIMIT, LOWER-LIMIT).Also found a couple of other symbol characters I missed.Ian.

author: IanJ
author_rank: Unknown
timestamp: January 09, 2025, 12:43:30 pm
content: Hi all,I have made some mods to my TFT implementation of the display.MOD. 1 - 9th Jan '25I have always wanted a 1 VDC range for the R6581. Now, we do get a 1000 mV range however I guess I am too used to my 3458A where it will display X.XXXXXXX VDC.So, I added a new mode whereby if you are on the 1000mV Range and you hit the DCV button it will switch the display out to a new 1 V Range.It gets its data from the 1000 mV Range and so you get an extra digit, one more than the 10 V Range for instance at max 8.5 digits.See photo below.The Blue Pill uses two additional inputs to interface to the DCV button, see photo below.Two are required because the button is multiplexed and I need two inputs to somewhat read a button press.GIT source =https://github.com/Ian-Johnston/R6581_VS_DisplayGIT .HEX file =https://github.com/Ian-Johnston/R6581_VS_Display/tree/master/VisualGDB/DebugOnly upgrade to this version is you hook up the new inputs to the DCV switch.New Pcb gerbers attached which include the new A11/A12 connections.Any issues then let me know (there are a couple of very small things).PS. For the coders, The Blue Pill doesn't have a hardware FP and the software FP was being a pain, i.e. I wanted to use atof but it just continued to return empty, so I wrote around it (ugghh!). There doesn't seem to be any downsides though. I’ll return to this soon as atof is a lot less code.UPDATE - 9th Jan '25Digital input A11/A12 logic tweaked.UPDATE - 10th Jan '251 VDC mode is now quite a bit more seemless, once it is set then it will remain in 1 VDC mode even if overrange or the DMM is in AUTO mode.GIT hex file updated.Still to do: try to reverse engineer the keypad better to fully isolate that button.UPDATE - 15th Jan '25Vertical Back Porch for TFT set to 11 rather than 10 (10 is per spec!) due to TFT flickering issue when running the R6581T for 20hrs.Possibly the a heat/stability issue with the LT7680A-R or the TFT itself. They do run pretty warm in there (I might look at a fan upgrade)!UPDATE - 16th Jan '25Horizontal Back Porch for TFT set to 30 rather than 20 (20 is per spec!) due to TFT still flickering issue when running the R6581T for 12hrs.I have attached the original HEX file and this new one.UPDATE - 19th Jan '25Fix issue where random pixels might appear at right hand vertical edge.See new HEX file.UPDATE - 20th Jan '25Display still flickering at times, found that TFT timings was incorrect, the TFT is 400x960 but with partial glass, i.e. -80. So, must be treated as 400x960 in software.See new HEX file.UPDATE - 23rd/24th Jan '25Still chasing the flickering problem which seems to return randomly, or temperature related.Porch and start timings - LCD_VBPD, LCD_VFPD, LCD_VSPW, LCD_HBPD, LCD_HFPD, LCD_HSPW1 - 17, 15, 1, 50, 30, 10 Haven't tested fully2 - 17, 15, 2, 50, 30, 10 Stable with freezer spray & heat gun, single vertical line at right3 - 17, 15, 3, 50, 30, 10 Flickers when cold, no vertical line4 - 17, 15, 4, 50, 30, 10 Flickers badly5 - 17, 14, 1, 50, 30, 10 Flickers badly6 - 17, 14, 2, 50, 30, 10 Stable with freezer and heat gun, has a single vertical line7 - 17, 14, 3, 50, 30, 10 Stable with freezer and heat gun, has a single vertical line8 - 17, 14, 4, 50, 30, 10 Stable (except once on startup) with freezer and heat gun, no vertical line - ORIGINALOption 6 seems to be the closest to the AdaFruit example but has a vertical line down the right hand side which I can't get rid of. It's the most stable.Well, I can by adjusting other parameters but it makes the TFT unstable (flickers).Wierdly, my other R6581T, and ADCMT unit, has no flicker or pixel issues at all.5 HEX files below to choose from:R6581_VS_Display_17_14_2_50_30_10.hexR6581_VS_Display_17_14_3_50_30_10.hexR6581_VS_Display_17_14_4_50_30_10.hexR6581_VS_Display_17_14_2_50_30_10_45HzrefreshR6581_VS_Display_17_15_2_50_30_10_45HzrefreshGerbers updated to V1.3 due to short across 3 tracks on the Pcb.Still to do - Allow adjusting of the timing via the front panel.MOD. 2 - 10th Jan '25When the LCD shows "DISPLAY OFF" i.e. when the user actions this via the menu, it now turns off the LCD completely (blank). Pressing the MENU button revives.It reduces the backlight to minimum, and turns off the LCD via register 0x12 of the LT7680.A user asked for this and I guess it's good for TFT long term saving especially for those running the DMM 24/7.UPDATE - 12th Jan '25Bug fix on the backlighting brightness control when implementing DISPLAY OFF.UPDATE - I HAVE MOVED MY TFT COVERSION PER BELOW LINK. This post will no longer be updated.https://www.eevblog.com/forum/repair/advantestadcmt-r6581-vfd-to-tft-conversion/msg5794969/Ian.

author: kt6ln
author_rank: Newbie
timestamp: January 17, 2025, 02:45:00 am
content: I made the conversion of my R6581T to Ian's TFT screen type.First many thanks to Mickle T. who started this journey with OLED display and then to Ian updating it to TFT. I am lucky to have benefited from both of their efforts to have a beautiful R6581T screen. I could not have made it alone.I kept in contact with Ian across the pond since his first PDVS (first gen) reference. He has been very helpful over the email frequencies!And we are still in email exchange to perfect the behaviour of the TFT screen for this application. He made the conversion process easy. If I can do it, everyone can, also.If you were wondering who the heck I am, I am a silent voltnut with a few 8½ digit multimeters in his arsenal. I call "silent" because I never posted anything on EEVblog before. But now, I feel compelled to write and encourage all voltnuts out there who also own R6581T. Try Ian's update if you have not done it already. If you follow his written instructions and video, you should have no problems.ismail

author: dietert1
author_rank: Super Contributor
timestamp: January 17, 2025, 04:44:44 pm
content: With all respect, the one who posted the first complete conversion to TFT was me.Regards, Dieter

author: jj131415
author_rank: Newbie
timestamp: January 24, 2025, 05:25:40 am
content: Hi Ian,I find the problem and fix it, your V1.2 PCB is wrong, 3 nets are shorted.Two suggestion:1.About the new FW Jan 23th, could you remove the right side vertical line? It's too odd. So I have to use the FW Jan 19th, no flickering is found now. But FW Jan 15th is more easliy to duplicate flickering by power on/off sometimes.2.Please stop the flashing green LED on bule pill board if possible.Thank you.

author: IanJ
author_rank: Unknown
timestamp: January 24, 2025, 01:39:47 pm
content: Quote from: jj131415 on January 24, 2025, 05:25:40 amThanks for pointing out the gerbers issue on V1.2.....no idea how that happened!I have updated my post above with Gerbers V1.3.All firmware prior to Jan 23rd will flicker at some point on one of my R6581T DMMs, it seems temperature dependent. It was only by using AdaFruit instead of BuyDisplay recommended settings that I was able to get the display stable, however this introduces a vertical line at the far right. This appears not to be addressable pixel data but some kind of timing leakage as it's beyond the 320x960. If you view from the left this line disappears!I cannot find a combination that has no vertical line and is completely stable.On one of my units I have to use R6581_VS_Display_17_14_2_50_30_10.hex and live with the vertical line, albeit I have a 0.5mm strip of black tape over it!I have updated my post above with 3 different HEX files to choose from.Ian.

author: jj131415
author_rank: Newbie
timestamp: January 24, 2025, 02:16:04 pm
content: hi Ian,Your test results shows that related to temperature, as my experience, maybe it caused by SI (signal integrity) issue. Could you have a try to reduce the TFT CLK frequency or frame rate? Give it engouh settling and hold time. I don't know if it can fix flickering problem.Some quick test results for your reference on my R6581D A02 FW:FW Jan 15th --- flicker @ 17C, no flicker @ 22CFW Jan 19th --- no flicker @ 17C, flicker @ 22CFW Jan 20th --- lite vertical line on the right, see random vertical line during power on/off, no flicker @ 17CFW Jan 23rd 17 14 2 50 30 10 --- vertical line on the right, see random vertical line during power on/off, no flicker @ 17CFW Jan 23rd 17 14 3 50 30 10 --- vertical line on the right, see random vertical line during power on/off, no flicker @ 17CFW Jan 23rd 17 14 4 50 30 10 --- very lite vertical line on the right, see random vertical line during power on/off, no flicker @ 17CFW Jan 24th 17 14 2 50 30 10 45Hz--- vertical line on the right, no flicker @ 17C/22CFW Jan 24th 17 15 2 50 30 10 45Hz--- no vertical line on the right, no flicker @ 17C/22CReport one bug on FW Jan 24th 17 15 2 50 30 10 45Hz:It display wrong text "BRA?" with 5~20 level frames during internal calibration. Correct text is "calibrating".See pic attached.Thanks.

author: TheDefpom
author_rank: Frequent Contributor
timestamp: January 24, 2025, 06:21:15 pm
content: Makes me wonder a bit if it is a clock or data polarity issue (or rising/falling edge SPI type), where maybe it is clocking at slightly the wrong time causing all the bits to shift to the left a bit?

author: ME
author_rank: Frequent Contributor
timestamp: February 18, 2025, 06:47:58 am
content: Someone should do a sticky on howto program an stm32 blue pill with the arduino ide, I gave up trying after following yt vids with no joy.

author: z01z
author_rank: Regular Contributor
timestamp: February 18, 2025, 11:40:39 am
content: Quote from: Mickle T. on November 21, 2024, 05:06:32 amThe schematic appears to be very similar, the wiring between the VFD and TD62C950RFs look the same, and the same pins are used on the H8 as well.Based on the R6581 connection diagram, the points shown in the attached picture are the equivalent points for the R6243.Edit: added another picture with different connection points, this might be easier to use.

author: z01z
author_rank: Regular Contributor
timestamp: March 21, 2025, 03:01:20 pm
content: Seems like the R6581 software works for the R6243 as well.Finally got it working, the DCV button needs a workaround here, without which only 2 thin lines at the LCD edge are displayed. A 10k pullup on A11 and 1k pulldown on A12 works.Thanks a lot for everyone involved in the development of this mod!

author: IanJ
author_rank: Unknown
timestamp: March 21, 2025, 03:50:44 pm
content: Quote from: z01z on March 21, 2025, 03:01:20 pmMy R6581 TFT thread is on this link (this one is really MickleT's OLED thread):https://www.eevblog.com/forum/repair/advantestadcmt-r6581-vfd-to-tft-conversion/Ian.