极品!高帽也顶穿了!
https://www.youtube.com/watch?v=PCimU5x25ic
极品!高帽也顶穿了!
https://www.youtube.com/watch?v=PCimU5x25ic
The most common mode of CRT display failure in the TDS 500~800 series (Monochrome models) is the flyback transformer. The symptom is that after leaving the screen on for a couple of hours, the screen started stretching vertically until it disappears.
It also happens the failure only happens to a batch of CRT boards. The batch I’ve seen looks new (with modern markings that tells you the purpose of the trimpots) and lightly used, so I’m sure it’s infant mortality. Here’s the broken CRT driver board to be repaired:
There’s practically nowhere you can find this obsolete replacement because it’s not a common configuration. I sourced a batch from China that claimed the part number, and I spent whole day cursing the vendor when the flyback transformer arrived. Here’s what I saw:
The one on the right was the broken original flyback transformer, and two on the left were my new orders. Not only that the shapes are completely different, the number of pins doesn’t even match. WTF?!!!
The seller told me that it works. Forget about how to fit that in the board for a moment. How the f*** am I supposed to know which pins goes to which spot? Not to mention there are 11 dots when the original only has 8+1 (actually 7+1, pin#8 is not used). I said dots instead of pins because not all of them are populated with a pin, and the pins that are missing were not even consistent across the transformers in the batch.
I cannot even guess with a multimeter because it’s not a simple, uniform transformer. Even if I know which ones are connected, I could have ruined the whole thing by having the wrong number of coil turns/inductances because I switched a pair or two!
I had to push the seller really hard for him to dig up the actual mapping and draw me the pinouts on the pictures I’ve sent him (I’m sure the whole batch will be trash if I could not communicate with them in Chinese). The ‘product’ must have been designed and the manufacturing line ran by a bunch of village idiots. Nothing is right about it other than the windings inside are electrically usable (can’t even say compatible because I need to hack it really hard to get the correct display). Here’s the pinout:
Here’s another transformer that doesn’t have the ground pin (unnumbered), turns out the transformer works without it:
The space inside the oscilloscope case is pretty tight, and I managed to find one orientation that lines up with the case nicely, but it’s ugly as hell:
I held it down with hot-glue, caulk to stabilize it. A rubber band was put over it so that if the glue fails, the transformer won’t roll inside the compartment causing mayhem (later units I used cable ties since rubber band might deteriorate with heat. You get the idea.):
If you are not a hobbyist and don’t want the hassle of disassembling whole bunch of stuff just to take out the CRT driver, rebuild it with the said flyback transformer and re-tuning the CRT driver (not only it’s a huge pain, the working room is very tight if you don’t have the extension cables), I recommend sending the unit to me for a full CRT surgery (you pay for shipping costs both ways). I also charge a lot less if you combine it with other services such as re-capping (strengthening), NVRAM replacement, etc, in one trip.
Update (2023/07/02): the prices 6 years ago is no longer practical. Luckily nobody asked. This surgery is just way too much hassle to charge this little. If you have a big customer who really need to keep exactly the same model to avoid changing their process/certification/software, ask me for a spot quote. I usually give very generous combined discounts if there’s more than one thing to work on.
I don’t think anybody else have new compatible flyback transformers for these displays that has the same fate anymore. I’ll update this post when the ones I saved are used up.
Call me at 949-682-8145.
I’ve seen a lot of ugly implementations from people trying to deal with variable number of input and output arguments. The most horrendous one I’ve seen so far came from MIT’s Physionet’s WFDB MATLAB Toolbox. Here’s a snippet showing how wfdbdesc.m
handles variable input and output arguments:
function varargout=wfdbdesc(varargin) % [siginfo,Fs,sigClass]=wfdbdesc(recordName) ... %Set default pararamter values inputs={'recordName'}; outputs={'siginfo','Fs','sigClass'}; for n=1:nargin if(~isempty(varargin{n})) eval([inputs{n} '=varargin{n};']) end end ... if(nargout>2) %Get signal class sigClass=getSignalClass(siginfo,config); end for n=1:nargout eval(['varargout{n}=' outputs{n} ';']) end
The code itself reeks a very ‘smart’ beginner who didn’t RTFM. The code is so smart (shows some serious thoughts):
nargout
to control varargout
to avoid the side effects when no output is requestedvarargin
so it can be symmetric to varargout
(also handled similarly). varargout
might have a benefit mentioned above, but there is absolutely no benefit to use varargin
over direct variable names when you are not forwarding or use inputParser()
.but yet so dumb (hell of unwise, absolutely no good reason for almost every ‘thoughtful’ act put in) at the same time. Definitely MIT: Make it Tough!
This code pattern is so wrong in many levels:
varargin
/varargout
varargin
and varargout
cells unnecessarilyeval()
just to do simple cell assignments! Makes me cringe!Actually, eval()
is not even needed to achieve all the remaining evils above. Could have used S_in = cell2struct(varargin)
and varargout=struct2cell(S_out)
instead if one really wants to control the list of variable names manually!
The hurtful sins above came from not knowing a few common cell packing/unpacking idioms when dealing with varargin
and varargout
, which are cells by definition. Here are the few common use cases:
C{:}
unpacks to comma separated lists!
function caller(varargin) callee(varargin{:});
[C{:}]
on left hand side (assignment) means the outputs are distributed as components of C
that would have been unpacked as comma separated lists, i.e. [C{:}] = f();
means [C{1}, C{2}, C{3}, ...] = f();
function varargout = f() // This will output no arguments when not requested, // avoiding echoing in command prompt when the call is not terminated by a semicolon [varargout{1:nargout}] = eig(rand(3));
function varargout = f(varargin) // This one is effectively deal() varargout = varargin(1:nargout); end function varargout = f(C) // This one unpacks each cell's content to each output arguments varargout = C(1:nargout); end
One good example combining all of the above is to achieve the no-output argument example in #2 yet neatly return the variables in the workspace directly by name.
function [a, b] = f() // Original way to code: will return a = 4 when "f()" is called without a semicolon a = 4; b = 2; end function varargout = f() // New way: will not return anything even when "f()" is called without a semicolon a = 4; b = 2; varargout = manage_return_arguments(nargout, a, b); end function C = manage_return_arguments(nargs, varargin) C = varargin(1:nargs); end
I could have skipped nargs
in manage_return_arguments()
and use evalin()
, but this will make the code nastily non-transparent. As a bonus, nargs
can be fed with min(nargout, 3)
instead of nargout
for extra flexibility.
With the technique above, wfdbdesc.m
can be simply rewritten as:
function varargout = wfdbdesc(recordName) % varargout: siginfo, Fs, sigClass ... varargout = manage_return_arguments(nargout, siginfo, Fs, sigClass);
Unless you are forwarding variable arguments (with technique#1 mentioned above), input arguments can be (and should be) named explicitly. Using varargin
would not help you avoid padding the unused input arguments anyway, so there is absolutely no good reason to manage input variables with a flexible list. MATLAB already knows to skip unused arguments at the end as long as the code doesn’t need it. Use exist('someVariable', 'var')
instead.
The general wisdom about eval()
is: do not use it! At least not until you are really out of reasonable options after consulting more than 3 experts on the newsgroups, forums and support@mathworks.com (if your SMS is current)!
Abusing eval()
turns it into evil()
!
The elves running inside MATLAB needs to be able to track your variables to reason through your code because:
eval()
cannot be pre-compiled)This is called ‘transparency’: MATLAB has to see what you are doing every step of the way. According to MATLAB’s parallel computing toolbox’s documentation,
Transparency means that all reference to variables must be visible in the text of the code
which I used as a subtitle of this post.
The 3 major built-in functions that breaks transparency are:
eval(), evalc()
: arbitrary code execution resulting in read and write access to its caller workspace.assignin()
: it poofs variables in its caller’s workspace!evalin()
: it breaks open the stack and read the variables in its caller’s workspace!They should have been replaced by skillful use of dynamic field names, advanced uses of left assignment techniques, and freely passing variables as input arguments (remember MATLAB uses copy-on-write: nothing is copied if you just read it).
There are other frequently used native MATLAB functions (under certain usages) that breaks transparency:
load()
: poof variables from the file to the workspace. The best practice is to load the file as a struct, like S=load('file.mat');
, which is fully transparent. Organizing variables into structs actually reduces mental clutter (namespace pollution)!save(), who(), whos()
: basically anything that takes variable names as input and act on the requested variable violates transparency because it’s has the effect of evalin()
. I guess the save()
function chose to use variable names instead of the actual variables as input because copy-on-write wasn’t available in early days of MATLAB. A example workaround would be:
function save_transparent(filename, varargin) VN = arrayfun(@inputname, (2:nargin)', 'UniformOutput', false); if( any( cellfun(@isempty, VN) ) ) error('All variables to save must be named. Cannot be temporaries'); end S = cell2struct(varargin(:), VN, 1); save(filename, '-struct', 'S'); end function save_struct_transparent(filename, S) save(filename, '-struct', 'S'); end
The good practices to avoid non-transparent load/save also reduces namespace pollution. For example, inputname()
peeks into the caller to see what the variable names are, which should not be used lightly. The example above is one of the few uses that I consider justified. I’ve seen novice abusing inputname()
because they were not comfortable with cells and structs yet, making it a total mindfuck to reason through.