Some short notes on the Lecroy9450 repair project

Because there is no big news yet, some short updates.

- Claude Schwarz pointed me to the Yahoo user group “Lecroy Owners group”, they have design files for a HHZ406 replacement. (Made by Dieter Frieauff). So maybe the ext. trigger input can be repaired as well.

- A service manual for this ‘scope (And others) can be found there as well, or alternatively here: http://www.ko4bb.com/manuals/index.php?dir=LeCroy (Or on elektrotanya.com – but that site is full of ads)

- NoTMS was caused by a missing “Vct”, I accidentally scratched trough this trace while placing the bottom cover. Took quite some time to find, then just a little wire to fix.

9450_scratchedVCT 9450_scratchedVCTFixed

- Thanks to Claude Schwarz (Again), I now have a third ADC card. So I now have spareparts, and if I get one of the 2 broken cards working again, a working 2ch 350Mhz / 400Ms/s (10Gs/s)  DSO. (Or rather: the Leidse Makerspace then has a 2ch 350Mhz DSO). The 3 ADC cards will hereafter be named “9450_3A Claude”, “9450_3A LMS-Broken” and “9450_3A LMS-Working”. (order shown in the picture, ltr: broken, Claude, working )

9450_3A ADCs

- I measured the power supplies on “9450_3A LMS-broken”. All are present. (-5V, -12V, 5V and +12V). Next up: reference voltages and tracing the signal path.

- Some more pictures:

lecroy_patchedOn some of the ADC boards, a 5V regulator is placed where others have just a cap.

lecroy_patched_2

This is another original patch (-5V regulator), both on “9450_3A LMS broken”. This board has no LeCroy repair stickers (shown below), but those patches were there when I got the ‘scope so I assume they are original.

Bot these 2 regulators and the -12V and 12V ones have the correct output voltages.

lecroy_repair

Lecroy Repair stickers on the timebase board. (This board is working fine) There are more of those stickers in the scope on other boards.

9450_errorlog

And the last one for today: The calibration error log. Chan2 has “9450_3A Claude” in this picture, but “9450_3A LMS broken” gives similar results. If I exchange the cards between the channels, ch1 gets the errors and ch2 is error-free. (The error-free channel has “9450_3A LMS working” in both cases).

‘ll keep you posted!

LeCroy 9450 oscilloscope repair

This was supposed to be an easy repair, and therefore not worth blogging about. But as it turns out, it might get interesting after all. (The ‘scope is not repaired yet)

The “Leidse Makerspace” owns a LeCroy 9450 350Mhz DSO. When they moved to their new location I temporarily got this oscilloscope. Not just for use or storage, but also to attempt to repair it. One of its channels was not working, sometimes it even wouldn’t display anything.

The display problem quickly turned out to be a loose connector. With this connector loose it would display nothing it al, or if it did work, it would sometimes glitch out like this:

IMG_6035_lecroy9450tobefixed

While at other times it would display normally:

IMG_6034_lecroy9450tobefixed

Probably just some transport damage, as after refitting this connector the problem has not been back. Now, on to the more interesting problem: channel 1 did not work: it did not respond to an input signal and it had a huge offset. After using the vertical position adjustment knob to bring it into view it would sometimes even oscillate on it’s own, showing needle-like pulses. The ‘scope also wouldn’t trigger on channel 1. Channel 2 functions fine, so it is still a usable 350Mhz DSO. However, 2 channels would be a lot nicer, and fault-finding is one of my hobbies. So… Time to remove the covers.

The easy-est way to measure in the analogue front-end of this oscilloscope is to turn it upside down, remove the bottom cover, remove the 12 screws holding the shielding, and remove the shielding.

IMG_6067_lecroy9450frontend

After this, an input signal can be followed, measuring before and after each subcircuit.
(I don’t have a picture of this, but I do have a picture of the 9450_7 front end, removed from the ‘scope, and from my annotated copy of the schematic)

IMG_6072_lecroy9450_7

IMG_6080_lecroy9450schematic

Close- up of the area of the board I’m looking at:

lecroy9450_7_detail

Somewhere here, the signal got lost. As you can see there is another module inserted through the pcb, this is the HHZ406. It turned out the signal entered this module (an amplifier), but nothing sensible got out.  IMG_6076_lecroy9450_HHZ406view from the other side of the board, also showing the relays. (Those metal cans)

IMG_6075_lecroy9450_HHZ406

This module does not look like it can be repaired, nothing is obviously visibly broken, and those “black blobs” don’t look promising either, because these usually cover (custom) semiconductors directly bonded to the PCB.

It also looks like it cannot be bought anywhere. Too specific, too custom… (If you know where to get these, or work for LeCroy and have spares, or if you would like to reverse-engineer them, let me know.)

But this story does not end here. This scope has 3 HHZ406 modules. One for each channel, and one for external trigger.

So I swapped the modules for external trigger and channel 1. After this, the signal got to the output of the 9450_7 board. When using the same V/Div settings on ch1 and 2, and feeding them the same input signal, the signals here would be identical.

The story does not end here either, however. Channel 1 still does not work. It does respond to an input signal and the ‘scope does trigger on this channel now, but the signal is not displayed properly. It has needle-like pulses on it. These pulses move when changing V/Div settings on the ‘scope or input signal amplitude from the signal generator. (Video: http://www.youtube.com/watch?v=wFei5CZ6lqA)

There is another defect lurking somewhere in the 9450_3a ADC boards, because when I swap them, the problem moves to the other channel (Ch2). Measuring on these boards is harder because they are not easy to get to while the ‘scope is operating, unlike the analogue front-end (9450_7).

IMG_6036_lecroy9450_3a_adccardsTo be continued (?).

Quick and dirty Arduino optical mouse sensor experiment (a2620 chip)

I wanted to experiment with a optical mouse sensor, did a websearch, found this blogpost, and adapted the code for my A2620 mouse sensor.  As it might be useful to others,  below is my Arduino sketch and the processing sketch.

Use the processing sketch to view the image from the sensor, or use a terminal program to ask it for X / Y movement.

IMG_5986_optical_mouse_a2620

(Yes, that thing to the left used to be a mouse… The thing to the right is an avrdb-m328 board used as an Arduino)

[ Arduino ]
#define FRAMELENGTH 324
#define SCLK 6 // portd.6
#define SDIO 7 // portd.7

byte frame[FRAMELENGTH];
byte flop;

/*
Serial driver for ADNS2010, by Conor Peterson (robotrobot@gmail.com)
Serial I/O routines adapted from Martjin The and Beno?t Rosseau’s work.
Delay timings verified against ADNS2061 datasheet.

The serial I/O routines are apparently the same across several Avago chips.
It would be a good idea to reimplement this code in C++. The primary difference
between, say, the ADNS2610 and the ADNS2051 are the schemes they use to dump the data
(the ADNS2610 has an 18×18 framebuffer which can’t be directly addressed).

This code assumes SCLK is defined elsewhere to point to the ADNS’s serial clock,
with SDIO pointing to the data pin.

Adapted for A2620 on AVRDBM328 by Luke.
*/

const byte regConfig    = 0×40; //a2620 . A2610 =0×00
const byte regStatus    = 0×41; //a2620 . A2610 =0×01
const byte regPixelData = 0×48; //a2620 . A2610 =0×08
const byte maskNoSleep  = 0×01; // unchanged for a2620
const byte maskPID      = 0xE0; // idem

const byte regYmov = 0×42; // a2620
const byte regXmov = 0×43;  //a2620

void mouseInit(void)
{
digitalWrite(SCLK, HIGH);
delayMicroseconds(5);
digitalWrite(SCLK, LOW);
delayMicroseconds(1);
digitalWrite(SCLK, HIGH);
delay(1025);
writeRegister(regConfig, maskNoSleep); //Force the mouse to be always on.
}

void dumpDiag(void)
{
unsigned int val;

val = readRegister(regStatus);

Serial.print(“Product ID: “);
Serial.println( (unsigned int)((val & maskPID) >> 5));
Serial.println(“Ready.”);
Serial.flush();
}

void writeRegister(byte addr, byte data)
{
byte i;

addr |= 0×80; //Setting MSB high indicates a write operation.

//Write the address
pinMode (SDIO, OUTPUT);
for (i = 8; i != 0; i–)
{
digitalWrite (SCLK, LOW);
digitalWrite (SDIO, addr & (1 << (i-1) ));
digitalWrite (SCLK, HIGH);
}

//Write the data
for (i = 8; i != 0; i–)
{
digitalWrite (SCLK, LOW);
digitalWrite (SDIO, data & (1 << (i-1) ));
digitalWrite (SCLK, HIGH);
}
}

byte readRegister(byte addr)
{
byte i;
byte r = 0;

//Write the address
pinMode (SDIO, OUTPUT);
for (i = 8; i != 0; i–)
{
digitalWrite (SCLK, LOW);
digitalWrite (SDIO, addr & (1 << (i-1) ));
digitalWrite (SCLK, HIGH);
}

pinMode (SDIO, INPUT);  //Switch the dataline from output to input
delayMicroseconds(110);  //Wait (per the datasheet, the chip needs a minimum of 100 µsec to prepare the data)

//Clock the data back in
for (i = 8; i != 0; i–)
{
digitalWrite (SCLK, LOW);
digitalWrite (SCLK, HIGH);
r |= (digitalRead (SDIO) << (i-1) );
}

delayMicroseconds(110);  //Tailing delay guarantees >100 µsec before next transaction

return r;
}

//ADNS2610 dumps a 324-byte array, so this function assumes arr points to a buffer of at least 324 bytes. (A2620: unchanged)
void readFrame(byte *arr)
{
byte *pos;
byte *uBound;
unsigned long timeout;
byte val;

//Ask for a frame dump
writeRegister(regPixelData, 0x2A); // wite anything to pixeldatareg to start at first pixel (A2620)

val = 0;
pos = arr;
uBound = arr + 325;

timeout = millis() + 1000;

//There are three terminating conditions from the following loop:
//1. Receive the start-of-field indicator after reading in some data (Success!)
//2. Pos overflows the upper bound of the array (Bad! Might happen if we miss the start-of-field marker for some reason.)
//3. The loop runs for more than one second (Really bad! We’re not talking to the chip properly.)
while( millis() < timeout && pos < uBound)
{
val = readRegister(regPixelData);

//Only bother with the next bit if the pixel data is valid.
if( !(val & 64) ) {
//Serial.println(“Invalid data.”);
continue;
}

//If we encounter a start-of-field indicator, and the cursor isn’t at the first pixel,
//then stop. (‘Cause the last pixel was the end of the frame.)
if( ( val & 128 ) &&  ( pos != arr) ) {
//      Serial.println(“last pixel read.”);
break;
}

*pos = val & 63;
pos++;
}

}

void setup()
{
pinMode(SCLK, OUTPUT);
pinMode(SDIO, OUTPUT);

Serial.begin(38400);
Serial.println(“Serial established.”);
Serial.flush();

mouseInit();
dumpDiag();

}

void loop()
{
int input;
byte buff;

//readFrame(frame);

if( Serial.available() )
{
input = Serial.read();
switch( input )
{
case ‘f’:      // capture frame
Serial.println(“Frame capture.”);
readFrame(frame);
Serial.println(“Done.”);
break;
case ‘d’: // dump frame, raw data
for( input = 0; input < FRAMELENGTH; input++ )  //Reusing ‘input’ here
Serial.write( (byte) frame[input] ); // use serial.write so it does not convert to ascii, –Luke
Serial.write( (byte) 127 );
break;
case ‘p’: // Powerup sequence
mouseInit();
dumpDiag();
break;
case ‘x’:  // read X movement register
buff = readRegister(regXmov);
Serial.print((byte) buff);
Serial.print(” “);
break;
case ‘y’:  // read Y movement register
buff = readRegister(regYmov);
Serial.print((byte) buff);
Serial.print(” “);
break;
case ‘s’:  // Shutdown
writeRegister(regConfig,0xE0);
Serial.print(“Shutdown”);
break;
case ‘i’: // Dump frame values seperated and human readable

for( input = 0; input < FRAMELENGTH; input++ ){  //Reusing ‘input’ here
Serial.print( (byte) frame[input]);
Serial.print( ” “);
// maybe find something to print LF each 18th datapoint?
}
Serial.print( (byte)127 );
break;
case ‘t’: // test image

for( input = 0; input < FRAMELENGTH; input++ ){  //Reusing ‘input’ here
Serial.write( (byte) input%64);
}
Serial.write( (byte) 127 );
break;

}
Serial.flush();
}
}
[ / arduino]

[Processing]

import processing.serial.*;

final int rate = 38400;
final int off_x = 75;
final int off_y = 70;
final int sz = 22;
final int frameX = 18;
final int frameY = 18;
final int frameLen = frameX * frameY;

Serial port;
int[] frame;
int serialCounter;

int nextFrameTime;
int framePeriod = 1000;

void setup()
{
size( 550, 550 );

frameRate(12);

frame = new int[frameLen];

initSerial();

noStroke();
noSmooth();
nextFrameTime = millis();

}

void draw()
{
serialHandler();

if( millis() >= nextFrameTime )
{
requestFrame();

background(245);

for( int i = 0; i < frameLen; i++ )
{
fill( map(frame[i], 0, 63, 0, 255) );
rect(off_x + (i % frameX * sz),
off_y  + (i / frameY * sz),
sz, sz);
}

nextFrameTime = millis() + framePeriod;
}
}

void keyPressed()
{
if( key == ‘f’ )
port.write(‘f’);

if( key  == ‘ ‘ )
requestFrame();

if( key  == ‘t’ )
{
port.write(‘t’); // test frame
serialCounter = frameLen;
}

}

void initSerial()
{
String portName = “/dev/ttyUSB0″;
port = new Serial(this, portName, rate);
println(“Using ” + portName + ” as serial device.”);
}

void requestFrame()
{

port.write(‘d’); // dump normal frame
serialCounter = frameLen;
port.write(‘f’); // request new frame
}

void serialHandler()
{
int incoming;
while( port.available() != 0 )
{
incoming = port.read();
print(incoming + ” “);
if( serialCounter > 0 )
{
if( incoming == 127 )
serialCounter = 0;
else
{
frame[serialCounter - 1] = incoming;
serialCounter–;
}
}
}
}

[/processing]

ESR LC meter behuizing

Ik ben momenteel bezig aan een ESR / L / C meter. In “Boem een blog” was al een foto te zien van het VFD, en een kort verhaaltje over hoe ik dat aanstuur.

Hierbij wat foto’s van de bouw van de behuizing. (Het oorspronkelijke plan was om gedurende de bouw te posten wat de voortgang was, maar de bouw heeft het posten ingehaald, de ESR/L/C meter is bijna af. Nu is “bijna af” wel het langste stadium van een project…)

Ik heb de behuizing gemaakt door vuren latjes aan elkaar te lijmen. Dat levert verrassend stevige kastjes op, en het is een makkelijker manier van bouwen.

Als je vragen hebt, over de esr-LC-meter: Laat het weten! Om een reactie op dit blog te geven hoef je geen account te maken en zelfs geen mailadres op te geven! (dat is, totdat ik teveel spam krijg).

De elektronica is natuurlijk een stuk interessanter dan gelijmd hout, dus vragen daarover zijn ook zeer welkom.

IMG_5910_esrmeter_behuizing
Haaks uitlijnen onder/bovenkant
IMG_5911_esrmeter_behuizing
Lijmen van de zijkanten
IMG_5913_esrmeter_behuizing
Behuizing in “houtskeletbouw”

Daarna moeten er nog plankjes op de zijkant gelijmd of geschroefd worden om er een dichte behuizing van de maken, en daarna kan de elektronica worden ingebouwd

DSCF0288_esrLCmeter_behuizing
Ingebouwde elektronica

Vervolgens komt er nog een stuk plexiglas op de bovenkant van de behuizing, waardoor de VFD afleesbaar blijft. Hierop worden dan ook de schakelaars voor de bediening gemonteerd. (Hier heb ik nog geen foto’s van)

DSCF0290_esrLCmeter_vfd
VFD in het donker

In het echt is de VFD gelukkig een stuk beter afleesbaar dan op de foto’s. M’n camera lijkt een hekel te hebben aan de specifieke kleur blauw/groen van de VFD. Wat wel goed te zien is op de foto is ghosting… Gelukkig valt ook dat in het echt mee, maar wellicht valt het nog wat terug te dringen door trager te multiplexen.

Hotglue reflow

Dit is hoe ik m’n iPAQ (h2200, h2210) z’n batterijklepje heb gerepareerd, met smeltlijm.

iPAQ h2210 battery door repaired
Gelijmd batterijklepje, BINAS op de achtergrond.

iPAQ h2210 battery door repaired

Om de een of andere reden plakt hotglue beter met een dun laagje tussen de te verbinden delen, ipv een dikke laag. Door met m’n heteluchtsoldeerstation de hotglue (en de te verbinden delen) warm te maken kon ik er zo’n dun laagje tussen krijgen. De warmte helpt ook om de lijm beter te laten verbinden met de te lijmen kunststoffen, en door het warm te houden blijft de lijm corrigeerbaar.
Die batterijklepjes schijnen nog al ‘s stuk te gaan, en nieuwe zijn schrikbarend duur (Een extended battery is goedkoper). Op deze manier kun je het zelf repareren. Bij gebrek aan een hot air reflow station kun je misschien ook een hairföhn gebruiken.

433Mhz spraak transmissie experiment met 1-bit ADC

Toen ik dit las vroeg ik me af of met zo’n 1-bit ADC verstaanbare spraak te verzenden zou zijn met zo’n goedkope 433Mhz module. En dan liefst met een heel simpele quick and dirty 1-bit ADC gemaakt uit standaard onderdelen.

En dat blijkt te kunnen!

M’n adc is geen echte adc, er is geen kloksignaal en de “charge injector” is een simpel RC netwerkje. Maar het werkt. Min of meer.

Geluidskwaliteit is zoals te verwachten viel beroerd, maar spraak is net aan verstaanbaar. (Als je geen idee hebt wat er gezegd wordt versta je het waarschijnlijk niet – als praktisch communicatiemiddel is het dus niet geschikt. Maar als experiment erg leuk.)

Goed, dat vraagt natuurlijk om schema’s, foto’s en filmpjes.

1bitadc schema
Het schema

Ik gebruik een LM358, 2x1k,2x47k,1x470k weerstanden, 1n en 100n condensatortjes, een microfoontje en een 433Mhz zendmodule. Aan de ontvangende kant: ontvangstmodule,1k,1n,piezospeaker.

1bitadc breadbord foto 1
Opstelling op breadboard

Vooraan de ontvanger, achteraan de zender.

Hier werkt de zender met een microfoontje. Maar dan hoort m’n camera me natuurlijk ook direct praten, zonder al die draadloze rommel ertussendoor. Dus heb ik een 2e test gedaan met een opname afgespeeld vanaf m’n pocketpc.

1bitadc breadbord foto 2
De zenderkant, nu met audiosignaal uit m’n pocketpc.

Filmpjes (Youtube)

Dit is een filmpje van de eerste test. Ik zeg “Dit is een spraakverstaanbaarheidstest”, en test later nog van een wat langere afstand. Tussen de spraak door hoor je alle andere rommel op de 433Mhz band. Deze test is met het microfoontje.

Dit is een filmpje van de 2e test. Ik zeg “if I did not want to repeat this test for Dutch and English I would have said: gratis T-shirts in the shop” Bij deze test speel ik de audio af vanaf m’n ipaq.

Het zou mogelijk beter werken met een echte 1 bits adc ipv dit quick and dirty ding. Misschien valt ook de functionaliteit van het quick and dirty ding nog uit te breiden.
Mocht iemand dat doen hoor ik er graag van :-)