Thursday, 20 July 2017

Rohde & Schwarz SWP.339.0010.02

I have a new thing to fix! It's a sweep generator that can produce signals from 400kHz to 2.5GHz and -130dbM to +13dbM. It's very big, heavy, old and broken!

So What's it Do?

This thing is a specialized  sweep generator that can quickly sweep across a frequency range. In addition to the RF output the generator produces a voltage which is proportional to the output frequency that you can use as the X input to your oscilloscope in X-Y mode. This allows you to produce frequency vs amplitude response curves for filters, amplifiers etc using the generator and a scope. It's pretty much the tracking generator part of a modern spectrum analyser. R&S sell other bits of gear that work with this one to provide network analysis and other features.

The thing uses a YIG (Yttrium , Indium, Gallium) tuned oscillator to produce the output frequency since YIG oscillators can be rapidly tuned over a broad frequency band. Unfortunately they are not frequency accurate without additional circuitry. R&S sell a 'synchroniser' option which is pretty much a fancy PLL circuit that allows you to lock the output to a crystal oscillator to get frequency accuracy. My unit has this option fitted.

In addition R&S sold a marker option and while my unit is fitted with this option I've not really touched it. I think it generates pulses so you can create tick-marks on your scope at specific frequencies.

Another option is the mechanical step attenuator that allows the unit to generate a broad range of output levels. Mine is also fitted with one of these which is pretty nice and it makes an amusing array of clunks as you wind the knob to adjust the output level.

Physically the thing is massive - weighs nearly 20kgs and is packed with boards.  It's got a huge linear supply with a shielded torroidal transformer and the back panel (which acts as a heatsink) gets quite hot when operating.



It has a big bright LED user interface and lovely clunky keyboard interface. The adjustment knob feels lovely to use as it is really solid and has a gentle cogging that feels a bit like a turning a very soft stepper motor. The knob will easily whizz if you flick it and it comes to a gentle stop.

I found the user interface a bit confusing at first - still do really. You have three numerical displays which are the start, marker and stop frequencies. The keys have second functions that are activated by a second function button marked with a red circle. To get a constant frequency output you have to use the second function button for example. There is an LED marked RF off and a button. By default the output is on unless you hit RF-off and then the light comes on. I feel is exactly the opposite of what I would expect.

I had no idea what 'synchronizer' meant and assumed it was something to do with interfacing it to a network analyzer. 'Synthesizer' would have made more sense as that is what this option does - makes the unit a synthesizer.


Condition

Overall the unit is in pretty good physical condition for its age (I think it is an early 80s device). There are little bits of corrosion on some boards/connectors which is concerning but probably Ok. It's got minimal amounts of the usual cal sticker residue and the paint on the rear and top/bottom panels is in reasonable state.

The first time I turned it on it was apparent the switch is broken as I had to hold it in to keep the unit on. This might have been transit damage.

In the ebay listing the seller noted it displayed error 10 A when the self-test runs. Before I bought the unit I looked this up and found it indicates the settings battery is dead. Could I be that lucky? When I opened it up I found the battery is in fact a pair of AA alkaline batteries and they had not been replaced in such a long time that they have eaten their battery holder. The battery doesn't matter too much as it is only used to store pre-sets. The unit operates fine without it.


I connected the unit up to my spectrum analyzer to look at the RF output but unfortunately it didn't look like it was working. The output was constantly around 38Mhz regardless of the settings. Doing this test  required some creative operation  as I needed to keep my finger on the power button to keep the unit on!

Power Button

First things first - the power button had to be sorted out as I couldn't do anything sensible with  the sweep generator while holding the power button in. The power button is at the back of the unit near the mains input and is connected via a long shaft to a power button in the front panel.

Knowing the likely outcome I removed and disassembled the power button anyway. The main shaft that is pushed by the rod has a hole for a pin that implements the push-on/push-off mechanism and this hole had been wallored out from many years of use.


I started looking for a replacement but the switch was made by Petrick and they went out of business long ago. The other problem was I found it pretty hard to find the right keywords to specify a push-on/push-off  plunger type switch with a square rod. It also needs to handle quite a few amps at 240V.

Even if I could repair the existing plunger I don't think the one I had was going back together any time soon :)



In the end I found a replacement switch that is a KDC-A04 and they are pretty common in cheap Asian electronics. They have the right number of poles, roughly the right throw and the right size plunger. The one problem was the size of the tabs used to screw it down where different. I found I could get enough purchase under the screw on the opposite side (even though the screw didn't go through the hole) for the switch to be pretty secure. I did have to slightly shorten the plunger but it worked just fine.


No Output

I got a partial copy of the user and service manual before I bought the unit from the R&S yahoo forum. Unfortunately these included the first 20 pages or so and the manuals are a mixture of English and German. I realized quickly that I needed more and began looking around for the rest of the service manual. The most economical option was to buy the two service manuals for 20Euro each from an online vendor. The paper manuals were nearly triple that! That's actually more than I paid for the generator!

Once I got the service manuals and started reading the more I started to figure out the self-test mechanism. The generator has an extensive set of self-test lines and can localise faults to some extent by itself. The first error displayed was the battery failure but you can hit the clear key to get past this and see other errors.

The first error was a failure of the 600MHz IF. This explains the lack of output. The other errors were likely a result of this first error.

How it Works

So the YIG oscillator generates frequencies from 4.2GHz to 6.7GHz. The output is generated by mixing this with an internally generated 4.2GHz signal generated from the 10MHz reference clock. The YIG is then tuned by sweeping the control voltage to vary the output frequency. This is all achieved within one of the large, RF shielded boards called the converter board. The block diagram below illustrates how this works:

The process is broken into:

  • A 100MHz VCO that is locked to the 10MHz crystal reference using a PLL
  • A frequency multipler to generate the 600MHz
  • A helical tuner to filter the 600MHz
  • An amplifier for the 600MHz signal (as it is used elsewhere in the unit)
  • A multiplier to generate the 4.2GHz signal from 600MHz
  • A filter for the 4.2GHz 
  • A mixer to combine the 4.2GHz with the YIG output

Debugging  down Rabbit holes

In my case the 600MHz was missing so I disassembled the converter and started tracing the signal through. The converter internally was quite interesting as it has a number of distributed element filters and a lot of hand construction.

Here you can see the 4.2GHz filter composed of the series of diagonal sections followed by a filter and at the top left is the mixer

The section at the top right is the 100MHz VCO and the bottom section to the right of the coils is the multiplier that generates the 600MHz from 100MHz. The  area at the top is the phase detector and frequency dividers etc that form the PLL.


The next trick was how to debug this. The case is quite closely packed so there is no hope of sneaking a scope probe down between the boards when they are in place. I found that R&S kindly supply a set of riser boards inside the unit that you can use to operate modules while they are up above the rest of the unit. The problem then is all the coaxial connectors that go in/out of the module which are all SMC (not SMA or anything common). I found a set of short SMC male to female patch leads that were perfect for the job on ebay. They look like this and allow me to connect the board to the coax cables inside the case


Running the converter board up on the extender boards with the patch cables plumbed in, I used a scope probe attached to my spectrum analyzer to measure what was going on. I found that the frequencies were way off. The 10MHz signal from the reference looked fine but...


The 100MHz was off a bit so instead it was more like 98MHz.


This got worse when it was multiplied so instead of 600MHz it was more like 589.


The output of the PLL PI filter was at the limits of the voltage range so clearly it was trying to force the VCO to 100MHz but couldn't. Because the 600MHz was so far off the filter was knocking it down a lot before it got to the next stage. Could this be the problem?

Apparently Not

I then looked at the service manual again. Apparently you can't operate the converter with the top cover removed as it effects the VCO (face-palm). Re-attaching the top cover and re-testing I found that the 100MHz signal was just fine as was the 600MHz coming into the following amplifier. What came out was pretty much nothing however. So in the schematic below the signal coming out of the 600MHz filter was fine but nothing was coming out of V82. What's more the test voltage at MP-10 and MP11 were off.



I also checked the circuit feeding V83 which is used to disable the 600MHz output (for example when re-tracing during a frequency sweep) but this appeared Ok.

So I ordered some BFR35 transistors and replaced V82 (feeling pretty sure this was it). I tested this again but no luck.

Intermittent

One really annoying thing about this unit is that the faults are very intermittent. I found that by fiddling with the controls it would randomly come good and start producing output. I figured out that the control that seemed to fix it was the one that disabled the output while the sweep re-traced.

I started monitoring the signal that disables HF output and looking at V249. See below.

On one of the occasions that this worked I realized that the 'HF off TTL' signal was effectively active-low. That is when the signal is high the HF is disabled and when it is low it is enabled. So actually when the signal coming in on pin C15 of the motherboard connector was high the output was disabled.

So actually the fault is elsewhere!

HF Enabled

The service manual is not much fun to read through. It's a huge file and so it is slow to scroll. The manual has been scanned as images so you can't search and it alternates the sections between English and German. Maybe this is because I don't have all  of the user manual but I couldn't find information anywhere that showed the location of each card. I had to effectively draw my own map by pulling each one out and comparing it with the drawings in the service manual.

Each schematic has the IDs of the connectors but then the cables have different designations and so it isn't always easy to figure out what signal is what and where it goes. The big block diagrams don't label the signals at all.

Now the HF off signal is referred to in other sections as HFSW1. There is also a HFSW and HFSW2 which are different! It turns out the HFSW1 signal is generated by the Sweep Control and Modulation amplifier.

So I connected up the sweep control and modulation board on the risers so I could start debugging this issue and half-way through I could no longer reproduce the fault. Before this I could re-start for the fault to return but now I can't in fact since then this fault has only come back a couple of times.

So I have to put this fault on the back-burner for now as I can't fix it if I can't reproduce it.


Next


So now it produces an but the frequency is pretty far off. The synchroniser does a good job of locking the frequency to the crystal but between 20.0MHz and 70.0MHz it totally looses it.

More debugging next time!

Friday, 5 May 2017

Spring Scheduling

I had the need to implement a periodic process where the period between runs was configurable from a properties file. I am using Spring with XML descriptors so this is a brief how-to on getting this working.

Scheduler

Spring implements a task scheduler and a task executor. My understanding is you need both to run a scheduled task. To add one of these to your spring application you have to add the task schema to your descriptor like this:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd>

Then you add these lines to configure a scheduler and a executor. In my case I only wanted this to be executed in one thread.

        <task:annotation-driven executor="scheduleExecutor" scheduler="scanScheduler"/>
        <task:executor id="scheduleExecutor" pool-size="1"/>
        <task:scheduler id="scanScheduler" pool-size="1"/>

Scheduled Code

The code to be scheduled was created using an annotation. The class was annotated as a component and the method to be called was annotated with the @Scheduled annotation so spring picked it up.

The documentation describes how to use the fixedDelay, cron etc parameters to control how frequently the scheduled operation runs but I needed this to be controlled from a properties file. I found that I could use a property-placeholder to load a properties file and use this in the @Scheduled annotation.

First add the place holder in your XML above the component scan

    <context:property-placeholder location="WEB-INF/tuning.properties"/>
    <context:component-scan base-package="com.somecompany.myproject"/>

Then you can use the fixedDelayString argument to the @Scheduled annotation to access a property (called transactionScanTime in the tuning.properties file)

@Component
public class TransactionScanner
{
    @Scheduled(fixedDelayString="${transactionScanTime}")
    public void scanTransactions()
    {
        // ...
    }
}


Wednesday, 26 April 2017

Two repairs

So I recently did two more repairs although neither was terribly interesting and I didn't take enough photos. Still worth a quick entry though.

Sharp JH1600E Solar Inverter

I am a member of a small sailing club and a few years ago the government were offering what was probably a way to generous incentive for people to install solar panels. They would pay 66c per kW.h for the electricity you produce where here in Australia we pay around 25c when buying the same power off the grid. I signed up the sailing club and the unit paid itself of in around 18 months and then continued to pay healthy dividends for the next few years.

The scheme ended last December and now they only pay 6c per kW.h for electricity produce but we now have the option of changing to a nett metering system so we can consume the power we produce and save 25c per kW.h consumed.

The inverter also went out of warranty at about the same time and then within a few weeks of this it failed. We got quotes of between $350 and $450 for repairs but when we earn so little from the system this becomes a major outlay. Interestingly these units seem to fail often and there are a lot of broken ones on ebay. The company that repairs them seems to be doing a good trade.

I decide to have a shot at it. The concern is if I get it wrong the unit could catch fire and damage the sailing club (which is empty most of the week so nobody would notice until it was too late). Trusting that the circuit protection will save the club I had a go anyway.

There is a service manual for the unit here but it only contains a block diagram and no schematics. As you'd the service manual shows a DC boost converter (to level the DC voltage coming in off the solar array) feeding a full-bridge converter. There is loads of EMI protection (both DC and AC) plus transient protection. The system can monitor the DC voltage, AC voltage as well as the power being pushed back onto the grid. There are loads of temperature sensors so it presumeably can shut itself off in case of trouble.

The unit failed after a thunderstorm. The AC breaker had opened and the system reported an F01 error indicating it didn't have a grid connection. Restoring the breaker didn't fix it so I dug deeper and found there is a 20A fast blow HRC fuse between the breaker and the AC output of the unit and this had opened. I ordered some of these, replaced the fuse and the unit then detected the grid and began its sequence to connect to the grid. As it got towards the end it made a loud pop, opened the AC breaker and destroyed the fuse again.

My theory was that a MOSFET in the full bridge converter had failed short either due to heat (it has been *really* hot here last summer with days as high as 47C) or line transient.

Taking the unit apart wasn't much fun. You have to unscrew the end caps, undo the bolts holding the lower section on, undo the screws holding the outer extrusion on and lift it off. Then you are looking at the bottom of the board so you have to unscrew the heatsinks from the back panel and lift the board out (which is insanely heavy).

There is a digital board on top that interfaces with button, generates the warning lights and has the LED numerical display. The main board has a small daughter board that contains the controller for the main inverter but this is hard to access and soldered in. The main board is conformally coated also which made just getting continuity readings difficult.

After some poking around with a DMM I found one MOSFET that was a dead-short. Even though it was screwed to a heatsink I had to desolder the four MOSFETs on that heatsink and unscrew the heatsink from the board to get it out as there was no clearance to get a screwdriver onto the transistor.

Here you can see the heatsink desoldered and unscrewed. In the forground are the heatsinks for the AC EMI, the DC boost converter and .. actually I'm not sure what the other one is. Lots of fist-sized transformers for filtering. There are some massive capacitors for the DC coming in (left side) and loads of MOVs inside little sleeves complete with thermal fuses.

The transistor was a SPW47N65C3 from Infineon. Unfortunately it wasn't carried by RS or Element14 so I had to get one from Xon (via ebay) for an eye-watering $28.

There wasn't really a safe way to test this and in fact it was going to be difficult trouble shooting the unit unless I partially re-assembled it. I couldn't find anything else that looked suspicious so I took a chance and put it back together with the new transistor. Sure enough it worked fine (with a new fuse) so the repair was a success.

The only annoying thing was I somehow lost a space for the selection button and haven't been able to get that working again. Given how much effort it takes to disassmble and reassemble the device I decided I would fix that another day.

DENON DCM-270 Five Disk CD Player

This was my sister's CD player from the 90s that started to skip and have problems playing CDs. It got worse progressively until it wouldn't play CDs at all anymore. When I tested it the unit would spin up the CD, click the focus a few times and then stop and move on. It couldn't even read the table of contents.

I found a service manual for the unit complete with schematics and exploded diagrams. The schematic was truly awful - lines everywhere and the lines were so illogically laid out it made the whole thing really hard to follow. The device uses a bunch of special purpose ICs for controlling the motors, processing the signals from the CD mechanism and decoding the audio. Thankfully the manual showed internal block diagrams for these so you have some clue what is going on.

First off I checked the power supply and inspected the board. There was a big hots spot around the -26V supply and signs of corrosion near a capacitor. The capacitor measure ok in circuit and the voltages looked ok so I moved on (more on this later).



From some googling I discovered that the usual failure mode of these devices is the laser sled. They use a pretty common Sony KSS213C mechanism and these are available all over ebay. I ordered a replacement and parked the troubleshooting.

When the replacement mechanism failed I found that it worked worse than the original! The replacement mechanism didn't even spin the disk where the original at least tried to read.  I checked the motors and they were fine (I could make them go with my bench supply).

I started looking at the Sony chipset used to drive the CD mechanism and decode the signals. Meanwhile I was trying to understand how the mechanism worked and understand what was going on.

A Quick CD Player Primer

So the CD mechanism had connections for:
  • The disc motor
  • The sled motor (to move the laser)
  • Laser focus
  • Laser power
Then it had a bunch of other connections labeled A-E. It turns out these are opto-diodes and the way they work is quite clever. The opto-diodes are arranged as follows (see below - this was stolen from here ).
                     |<--- ----="" array="" photodiode="">|
                               +---+---+
   ---------_________ +---+  +-| A | B |-+  +---+
   Track--->          | E |- | +---+---+ | -| F | ________
                      +---+  | | C | D | |  +---+         ---------
                        |    | +---+---+ |    |           Track--->
                  /|    |    |   |   |   |    |
    Focus       / +|----|----+---|---+   |    |    
    Error o---<    |    |    |   |   *   |    |    |\
    (A+D)-(B+C) \ -|----|----|---+-------+    +----|+ \       Tracking
                  \|    |    |   *       |         |    >---o Error
              FE Amp    +--------------------------|- /       (E-F)
                             |           |         |/ TE Amp
    * Since the photodiodes  |           |           
      are current sources,   |           |         |\
      the simple junctions   |           +---------|+ \       Data Out
      implement a sum.       |                     |    >---o RF Test Point
                             +---------------------|- /       (A+B+C+D)
    All Amps: current mode inputs.                 |/ DO Amp

So there are 6 opto-diodes in total (A-F). The four centre diodes are used both the read the disk and to keep the laser focused on the disk. The laser optics cause the laser spot to become elliptical along one or other diagonal depending on if the focus is to close or too far. By comparing the power at A and D with the power and B and C you can tell if one diagonal has more brightness than the other. This tells you if you need to focus in or out.

The focus mechanism has to be accurate to within 1um (!!) and this is while the disk is moving at 500RPM and could even be a little warped (spin unevenly).

The E and F sensors are placed such that one is inward of the current track and one outward. By comparing the power detected by E an F the mechanism keeps the track centred. The track is a continuous spiral over the whole CD. The data on the disk is read by summing the four centre detector outputs (A-D).  

The encoding of the disk data is such that by tracking the signal edges you can detect the speed of rotation. The system uses this to manage the rotation of the CD and keep it at a fixed velocity (using a PLL).

CD Chipset and Debugging

The CD player uses a Sony CXA1782BQ for the RF signal processing and CD mechanism servo control and a Sony CXD2500BQ to handle the signal processing of the CD data.

I figured out that the CXA has a FOK (Focus Ok) output and with the original mechanism in the CD player this would go high while it tries to read the CD but with the new mechanism it didn't.

I assumed the mechanism was broken and worked with the original. I was trying to understand what was going wrong as clearly the motors were working and I could hear the laser focus operating.

I found there was an RF_O signal that is effectively the processed data signal coming off the CD. This is supposed to be very closely synchronized and you should be able to measure the jitter in the CD speed control by triggering the oscilloscope of either the positive or negative slope and viewing an 'eye' diagram of the signal. In the case of this CD player the signal was a total mess. You could see the waveform get shorter as it speed up the disk to try and lock onto the signal but it was like the waveform was moving up and down (i.e ripples at the top then bottom).

I looked at the FE (Focus Error) output but this too was pretty messy and it wasn't clear if it was failing to focus, failing to track or what. I wasn't sure if the problem was the mechanism or something else.

Mechanism

So I thought maybe the laser power was too low and this was why it couldn't get a good signal. I read that you can't really adjust the power without a power meter since if you even slightly over power the laser diode it will fail in a matter of hours. I took a risk and turned up the power on the new mechanism but it responded exactly as before (no focus).

Doing some more reading I found out that new mechanisms are sold with a solder bridge across a critical spot on the board. This is to prevent damage from electrostatic discharge through the board during transit. I found this guide explaining where the bridge was located and how to remove it. With some excitement I removed the bridge on the new unit and installed it in the CD player. Unfortunately while it now spins the disk it still didn't read the CD. Basically it was the same as the original mechanism.

There is a FE (Focus Error) bias adjustment pot on the board and I tried changing this. I noticed that if I adjusted this I could make the problem worse but not better. When it was worse the player wouldn't spin the disk or would give up reading the TOC sooner.

Back to the Power Supply

Removing and re-fitting the laser unit is quite difficult and requires the removal of a number of connectors from the main PCB and removal of the CD loading mechanism from the chassis (as you can only access the laser unit from the bottom). I had done it a few times now and at some point I must have left the power connector for the front panel off and when I re-connected it the VFD didn't come on.

I decided I needed to tackle this. The VFD supply is powered by a separate transformer tap but is referenced to a -28V supply generated from another transformer tap. After a bit of poking around I realized this was missing. The -28V supply is generated with a pretty dumb linear supply consisting of a PNP transistor and a 27V zener diode. It turned out the zener was a dead short in both directions so I replaced it. This brought the supply back and now the VFD worked again.

The CD reading still didn't work however. While looking at the RF_O signal I noticed that even when it wasn't reading a CD there was a bit of noise. The noise looked like a 2MHz signal but only at about 200mV. At some point it dawned on me that this is actually a pretty significant proportion of the RF signal amplitude and is probably why the signal is so messed up.

I then proceeded to go hunting for the source of this noise. I think in part I ignored this before as I assume it was just bad grounding but even with the ground point closer to the power supply section the noise is loud and clear.

The CD Player has +14V, -14V, 8V which is generated by a monolithic regulator and 5V which is generated from the 8V by the motor driver chip and the -28V I fixed above.

The corroded cap in the image above was part of the -28V circuit so I decided I would replace it anyway. I pulled it out of circuit and the ESR measurement was through the roof at over 10K plus the capacitance was way off what it should be. I replaced it but the noise was still there (maybe a little less).

I found the 8V signal was most noisy and the 5V signal was also pretty noisy. There is a transistor controlled by the motor driver that generates the 5V line and this had an output capacitor. This tested Ok in circuit but I replaced it anyway. When I pulled it out of circuit the capacitor measured way off spec and again a very high ESR.

Replacing this capacitor fixed it! The RF_O signal now looked as it should and the CD player played CDs! I stepped through tracks and left it running for about an hour and all was well. I replaced a few more capacitors that looked suspicious but overall this was the extent of the repair.

So at least I learned a few things about CD players. I now have a spare Sony CD mechanism too.



Monday, 10 April 2017

R&S Give Away

Count me in for the Rohde and Schwarz RTB2000 Oscilloscope giveaway! And here is why!

MJLorton is giving away a RTB2000 oscilloscope on his channel so in part this post is in response to that but also this post is a bit of a whinge about Keysight.

MSOX2000 Gripes

I have a beautiful MSOX2024 that I've had for two years or so. I bought it as a re-furb unit and added a couple of options (expanded memory, I2C/SPI decoding). It has super fast waveform update rate, its really nicely built and pretty easy to use.

There are a few things I really wish the scope did:


  • Segmented memory (history R&S call it) so I can capture multiple serial or analog events over time and see each one.
  • General serial decoding. When I was working on my power supply project I could have really used this to decode serial problems caused by dodgy soldering of fine pitch chips!
  • Decoding of serial signals on the digital ports. I don't get why this limitation exists and this is pretty annoying.
  • LAN interface so I can automate some measurements.
So the first two things are additional software options I don't currently own. The list price segmented memory is $AUD450 and RS232 is $AUD737. That's nearly half what I paid for the scope!

There is an 'Application bundle' that includes everything for $AUD1820 but there is no discount for the options I already purchased.

No serial decoding on the analog channels is a real PITA. The problem is if you are trying to decode a bidirectional SPI signal you have used up all your channels and can't look at anything else. At this point you may as well be using a cheap USB logic analyzer as your correlation with analog has gone out the window. You can cheat to some extent and use clock-timeout instead of a dedicated CS line but in my case there were multiple SPI devices on the bus so that wasn't going to work either.

The digital probes also make much more sense for this type of work as they are fine and better suited to attaching to a wedge or the legs of  chips etc.

The only way to get serial decoding on digital channels is to upgrade to a MSOX3000. The cheapest one I would consider is a MSOX3014 and these start at $AUD10K. I found a re-furb with no probes for the bargain price of $AUD6500. They are a very nice piece of kit but this is well out of hobby territory. The application bundle is an eye-watering $AUD4500 (but it does include a lot of stuff).

The cost of the LAN card for these scopes is insane - $AUD400. Ok it has a VGA adaptor too but I didn't actually want that. I managed to work around this as many people have reverse engineered the LAN interface and provided PCBs. I got a PCB, assembled it and got around the problem.

While on this topic there is a rich thread over at the EEVBlog forum on how to hack this scope (via the LAN interface) to enable all the software options. Based on the prices above you can see why!

R&S RTB2000

I've been watching a number of reviews of this scope by MJLorton, Dave Jones at EEVBlog and Mike's Electric Stuff.

What most impressed me was:
  • The big, clean hi-res interface. I love the numbers on the graticule!
  • 10 bit converter and therefore the nuts low signal performance. I've been using my old analog scope for this as the lowest I can go with the MSOX2000 (and a x10 probe) is 10mV per division.
  • 16 digital channels, multiple serial decodes on digital or analog channels.
  • 'History' (segmented memory)
  • LAN!
The cost is still steep but element14 are offering the fully-loaded model for $5AUDK which is comparable with the MSOX2024 with no software options.

Active probe interface would have been nice. Not for hig-speed differential but for current probes or high-voltage differential probes etc. It would also be nice if the scope makers got together and standardized this! FFS!

Conclusion

Maybe I will get lucky and MJLorton will post me a scope but in all likelihood I'll be waiting for another second hand unit to come by.

I get that a lot of engineering goes into these units and they need to earn a crust but I still find their pricing structure steep.

Some of these options aren't really options though - are you going to buy a scope with 100K points of memory per channel? No LAN interface? I wouldn't (not again anyway) so really listing the memory upgrade etc separately is just a way of hiding the real scope price. Serial decoding is another example.

Surely there is some value in putting their kit in the hands of home-gamers like me (as AvE calls us) as one day we might buy a lab full of their gear (most hobby electronics people are students but some might be one-man shops that eventually go-big with a product). They don't though - they assume we are going to spend as much as a university and so instead we go buy Rigol or Siglent and make do.

Maybe the 2000 wasn't the right purchase for me.

Tuesday, 7 March 2017

GW INSTEK GSP-827 Sprectrum Analyzer Repair

I was lucky to find a GW INSTEK GSP-827 for sale in Australia. The advert said it had a screen issue and didn't pick up any RF signals. I managed to buy it quite cheaply (or cheaply enough that I felt I could get it past SWMBO).

It's not a particularly high-end unit. For starters it has a monochrome screen and it's RF specs aren't stellar (phase noise, sweep rate etc). It does however go from kHz up to 2.7GHz and importantly it has the tracking generator option fitted.

How it came

The unit was packed really well and the whole thing was really clean and tidy. There was a sticker on the lid listing a capacitor and a couple of resistors that had been replaced. These turned out to be on the motherboard.

The seller was a nice chap and explained that he bought it at auction from a College of Technical and Further Education (TAFE as they are known here). He hadn't gotten around to repairing it and had other (better) instruments so decided to sell it as-is.

The unit was as he described in that it powered on, the bottom half of the screen was messed up and when I adjusted the trace so I could see it at the top of the screen, I couldn't get it to respond to an external signal. All the functions I could see seemed to respond and when I enabled the tracking generator I could see a signal on my scope at the tracking generator output. There was a 10MHz reference out at the back and when I brought up the system config screen (in the bit I could see) it said that all three LOs were locked.

My guess at this stage was (a) the screen issue was a due to a hot-bar attachment on the LCD and (b) the unit was deaf due to having been overloaded by a TAFE student.

Screen Repair

I started taking the unit apart and was pretty impressed by the construction. It is a motherboard with a series of plugin boards and the whole thing is pretty tidy. Each screw is threaded and everything is nicely tied down.


I decided that repairing the screen would make repairing the rest easier so I started there. The screen looked like this when I ran the unit (at this point I had taken the screen out).


I took the diffuser and the backlight off the back of the LCD screen and looked for bad joints etc. I tried heating (with hot-air) and pressing the screen down but none of this seemed to make a significant difference. At a couple of point the screen did change as I was pressing on the board at the edges which made me think it must be the screen.

I couldn't understand how it could be anything but the screen since only half was not working. I felt that if it was a cable issue then all of the screen wouldn't work. 

One confusing thing was that the date/time at the top of the screen was messed up - the year was a big number and the last digit of the seconds would count up to 9 then turn into a '>' symbol.

Do we have a signal?

The LCD signal is generated from the DSP board of the analyzer. The EPSON chip at the top left is a S1D13705. There is an SRAM right next to so I suspected the problem might be with that. There isn't an easy way of determining this however. There is a LVTHR16245  between the EPSON chip and the LCD connector which I think is just a level translator/driver. The board had loads of these at each interface. The nearest datasheet I found for the EPSON chip was a S1D13700 which I thought might cover the whole family and this described the signalling to the LCD.



While we are here I thought I would mention the red/black wires at the top of that photo - these go to a coin-cell battery that was in a holder screwed to the case above the power input. There is a Dallas semiconductor DS1689 that manages the current time plus it holds a small amount of NVRAM that no doubt is where the options configuration is stored! I really didn't want to lose my tracking generator option so I was careful not to short this thing. No idea why an instrument this modern would use this ancient crap instead of EEPROM.

I ordered a replacement EPSON chip as I knew these take weeks to come from China but I decided to try and analyze the signals going to the LCD to see if there was data on the bottom half.

The pin pitch was too fine to directly attach logic probes and there was a series of resistor packs between the driver and the LCD so instead I soldered wire-wrap wires to these.


It's a bit of a mess and hard to connect up when the DSP is in the box as I can't use the microscope. It looked like this connected up.

There are 12 lines but I can only connect 8 as that is how many logic channels I have on my scope.

The EPSON datasheet described the signalling as :
  • FPFRAME that is pulsed once per frame start
  • FPLINE pulses once per line
  • YSCL which clocks once per pixel
  • FPDATA[0-3] which is a 4 bit data bus containing the grey level for each dot.
There is other stuff like a method of disabling the displace etc.

I wasn't sure what line was what but after connecting some up I found the lines described above. Here is a snapshot showing the timing of the FPLINE pulse. As you can see the frame-rate is around 77 frames per second.


If we zoom in, here is the timing of the line pulse. 


And finally zooming further we can see the timing of the pixel clock pulse.

After I was finished being chuffed by how my fancy scope can hold all of this in memory at once I started looking at some of the timing information. So the clock pulse period is 320ns and the line pulse period is 53.4us - that works out to 166.8 dots. This doesn't make sense but reading the EPSON datasheet a bit further it turns out the YSCL only occurs every 4 pixels which gives us 667 which might be near enough to 640 dots.

Then the frames period is 12.9ms and the line period is 53.4us which works out to 241 lines. This isn't nearly enough - in fact it is roughly half of what I expect.

Next I wanted to know if I watched the data at the end of the frame - i.e. just before the frame pulse - if I would see changes. The data doesn't change much unless you adjust the amplitude so there is something going on in that bit of the screen (which is tricky as you can't see it) but I managed to do it and sure enough the data did change (see video below). So that means it has to be the LCD panel right as we have data for the bottom half of the screen.




video

Replacement LCD


I decided I would order a replacement screen. The screens has a bunch of numbers on the back include LM64K112 but the datasheet for these was pretty brief and mostly just the mechanical specs. Some places that sell these list them as 320x200 which makes no sense as there is no way the screen res is that low. 

It also had a part number of LTBGCHB91J1K and I was able to find a screen with this part number on Taobao for a reasonable price. All the matching screens on ebay were $120-$200AUD which is a significant amount of the price I paid for the unit!

I ordered the screen and waited. Taobao was a bit of an adventure actually since it is all in Chinese. I had to use Google translate at every step to figure out what was going on. Amuzingly Taobao roughly translates as 'treasure network' and they refer to items as treasure (baobei). The funny thing about that is google translates this as 'baby' so every screen is filled with stuff like 'baby arrival' and 'baby attributes' etc etc.

The screen came and with some excitement I plugged it in and... it still didn't work! In fact when I first plugged it in it didn't work at all (totally blank) which turned out to be significant later.

So what is it?

At this point I was really stumped. The last number on the back of the LCD was HDM6448-1. I searched on this before but this time I found a datasheet! The interesting thing is this LCD has the same control lines I described above but has two sets of bus lines for the pixel data! One for the upper half and one for the lower half. Also now I know what pins are what it's easier to track. This also explains how half the screen could fail.

But the EPSON chip didn't mention any of this. I searched a bit harder and found there was a datasheet for the S1D13705. It turns out this unit can support either 8 bit colour displays or monochrome 'dual' displays like the one the analyzer has.

So I checked the signal on one of the lower screen data lines at the EPSON chip and sure enough I can see signal. Then I repeated this at the LCD connector on the DSP board and I can see a signal there too. Finally I checked the signal on the LCD panel itself and there was no signal! One line sometimes worked but three didn't,

I pulled the flat-flex cable off at both ends and checked its continuity - sure enough some of the lines were dodgey. Face-palm! All this work and it was a bad cable! Under the microscope you could see the break right at the fold in the cable near where it is stripped back to go in the connector.

I spend a long time looking for a replacement cable and the nearest I could find was expensive and in the UK. I thought I would have to buy it but before I did that I would try soldering the wires back together. This was a disaster as it melted the cable and caused the broken bits to float off and stick to my iron etc.

My next idea was to trim off the end (at the break) and *very* carefully scrape the insulation off to reveal new conductors. This worked pretty well and looked ok. I plugged it into the unit and guess what!


RF Problem

So given that the local oscillators are all fine and the tracking generator is fine, I thought the problem is likely to be at the front-end of the instrument. This part of an spectrum analyzer is highly susceptible to damage from overloading also and the unit did come from a teaching lab.

I pulled the RF module out - it has a billions screws holding a cover onto a diecast frame that is held in with another billion screws from the PCB side.


I removed the covers to see the components.


I was greeted with the usual RF voodoo in the form of distributed element filters, RF absorbing pads and lots of MMIC amplifiers and hybrids,

It's pretty easy to follow as each little box is a different circuit stage. The front-end consists of a capacitor to couple the input followed by some resistors and some very fast diodes. The diodes will open if the input power is too high and the resistors limit the current.

The diodes are a likely source of failure but they are hard to check in circuit. Also they are under the edge of the first box which makes it doubly hard to test them and impossible to remove them. To make matters worse, when I removed the bottom side screws to remove the die-cast frame I realized I couldn't because the N type input connectors is threaded through the frame and soldered onto the board!

So I broke out the soldering iron and braid and had to de-solder the damn thing to get started. I decided I wasn't doing this again so I cut a slot in the die-cast frame so I could get it on and off in the future (Grrr!). Admittedly this is the only part of this unit's physical construction that annoyed me so far.



So here is the front-end circuitry out of the can - first the input cap, resistor pad and two diodes (right where the can edge was). I removed the diodes from the board and tested them. They seemed fine. I'm afraid I lost the details of these but they were a very fast PIN diode in SOT-3 package.


The next stage of the circuit goes through a series of attenuation stages that are switched using these Skyworks AS169 switches. They are a pretty cool bit of gear as they are Galium Arsenide ICs that are good for 2.5GHz or more.


Finally we end up at a MMIC amplifier just before the first mixer (which is under the RF absorber).


The MMIC is a Sirenza SBA-4086 which is a 2GHz 15dbm amplifier.

My plan was that if the problem is the first mixer then I won't be able to tell as it is way outside of the frequency range of my scope. If I inject a low frequency signal into the front-end however I should be able to see this at the output of the MMIC. I soldered a small wire on the board so I could tap the signal at this point and using my spring clip ground I attached a probe, I carefully stuffed the PCB back into the motherboard and powered it up.

I put a 0dbmV signal into the front-end (pretty loud in other words) and sure enough I got a strong 400mV signal at the amplifier. So the amplifier is find and so is the front-end up to that point.

Mixer

The mixer is a mini-circuits SKY-60 part, Unfortunately you can't buy these via RS or element 14 etc. I found some other SKY-60 parts (SKY-60MH etc) on ebay but the specs looked different enough that I didn't want to risk it.

You can buy them directly from Mini-circuits but the minimum order quantity is 10 and they are $12USD each. The Australian distributor is Clarke and Severn but they didn't have this part on their sight. I contacted them and they added it for me and I could order single quantities. The problem is they have to back-order it from the states so it would take a couple of weeks. Pretty cool!

GW INSTEK Support

When I started all this I contacted GW Instek support to see if I could get a service manual and/or parts. They took a little while to respond and initially asked for the serial number of my unit so they could forward it to the correct regional support. I expected they would come back and tell me where I could get it serviced but not provide anything else.

After I ordered the mixer I was pleasantly surprised that they came back and sent me a service manual. They said they couldn't give me schematics as I wasn't an authorized repairer but if I agreed to sign an NDA they could give me some info. This is way more than I expected (way more than many other big brands would offer). Massive thank you and kudos to GW INSTEK. While it's not as good as the old Agilent stuff where they publish full schematics in their service manuals it is understandable given the rampant copyright violations that happen in China.

Another look

Given I was stuck waiting for a part I thought I would try a few experiments. The service manual included block diagrams showing the path through the mixers and indicated the IF coming out of the RF board should be 452MHz. It also showed a 100MHz reference signal that got divided down by 10 to generate the reference signal on the back of the unit and got multiplied by 32 to generate the second LO.

I decided I would start by probing the IF signal since even though it is out of the range of my scope it still might be viewable. Weirdly the signal I saw was a 100MHz slightly distorted sine wave. When I fiddled with the frequency range and settings it didn't change.

The semi-rigid cables in the unit are slightly confusing. They are labelled but for example two of the cables going to the RF board had the same label. Others showed the J number of the connector but often the boards didn't have this silk-screened onto them. There are coax sockets with no connectors in them also.

Someone on the EEVBlog had problems with their unit having a 6dB offset. They published photos of the internals including this one (note they have no tracking generator like mine).


I must have looked at this 10 times but the cables on mine looked to be out of place. Also the markings on the cables indicated one was to go to the IF board and the other to the LO board but in my case one went to the TG board and the other the IF board (so they were one board out).

Here is how they were connected in my unit


Here is the shot from the EEVBlog showing the correct placement again.

Could it be that simple? I re-connected the cables, rebooted the unit and it worked! So now I just have to put all the screws back into the RF board :(


Screen Dim

So while it all works now the screen is very dark. There is a brighness control but it doesn't help much and seems to do nothing until it you get to a certain range and then it suddenly changes a bit.

I looked at how this works and there is a 13-24V bias voltage that goes to the LCD to set the brightness. I traced this on the DSP board and it went over to the other side of the board near the input. I found an 8 bit Analog devices AD5300 DAC (U13). This was connected to an OPA237UA opamp (U12) and a transistor (Q12). The resistor nearby (R88) is what connects directly to the LCD bias line and I noted (under the microscope) it had a hole in it!


Thankfully the service manual had the component values as the marking codes made no sense. It was a 27.4 ohm 0603 resistor and I had a 27 ohm one on hand and replaced it. This still didn't fix it so I watched the voltage first at the output of the DAC and then at the resistor to see what happens when I vary the contrast. The DAC output changed smoothly but the voltage to the LCD did this weird jump I could see from the screen change. The output of the opamp seemed to be going from one rail to the other across this jump.

The transistor was a MMBT3906LT1 accoding to the service manual and it is a general purpose PNP that can handle around 200mA. The only SMD PNP I have is a BC857 and that only goes to 100mA. Given this one died of over-current damage I figured I shouldn't risk it. Jaycar (bless their souls) recently started carrying some surface mount parts and the one surface mount PNP they carry is an BC807. As it turns out this is a fine replacement for the MMBT On-semi part so I bought some and replaced it. This worked just fine!

Conclusion



So here is the SA re-assembled and happily integrated into my bench. I can see the internal cal signal just fine and the power level is within a couple of dbmV of the specified -30. If I use the tracking generator the trace is flat right across the spectrum to within a few db (impressive! with my shit cable!). I found some N-type to BNC converters and am using my BNC cables for now. I've ordered some n-type to SMA and SMA cables. I'll need loads more bits and pieces to use this thing though.

So overall I am very happy indeed. Got very lucky with this purchase.


Friday, 3 March 2017

Using Spring Validation in Angular

I was recently working on a web project where I needed support for substantial modal web dialogs inside web pages. My first approach was to use what what was familiar to me which was  JSP with spring MVC controllers. The problem is this isn't very convenient with modal components as you  you have to manually bundle up  the value in the form with java script code and post it yourself.

So I started exploring Angular JS as a way of doing this and basically it took over my life (in a good way I think).

One are I struggled with was validation but I found a solution I was happy with and hence this post.

Problem

Since I started with Spring I had my models annotated with validation constraints like the example below :

 class User  
 {  
   // ...  
   @Size(min=1, message="First Name must be provided.")  
   private String firstName;  

   @Size(min=1, message="Last Name must be provided.")  
   private String lastName;  

   private String organisation;  
   @Size(min=1, message="Email must be provided.")  

   private String email;  
   @Size(min=1, message="Password must be provided.")  

   private String password;  
   private boolean isAdmin;  
 }  

Then the controller can validate objects of this type using the SpringMVC magic as follows:

 
   @RequestMapping(value="/user",method=POST)  
   public @ResponseBody ModelAndView editUser(  
       @Valid @RequestBody User user,  
       BindingResult    result)  
   {  
     if ( result.hasErrors() )  
     {  
       return ...  
     }  
    ...  

The BindingResult is then available in the JSP so you can write code in your form like this to display the errors (using some tag library stuff).

  
    <form:input path="firstName"   
       cssClass="field input medium"  
       cssErrorClass="field input medium error" />  
    <form:errors path="firstName" cssClass="error" element="p" />  

But if we aren't using JSP then how do we get these errors out? If we are using Angular then we post the form data as JSON asynchronously and the page isn't reloaded.

Outline

When I searched for a solution to this problem, the first things that came up were techniques for implementing validation in Angular. While its good to validate the content before leaving the page the problem is you still have to validate the content at the server as otherwise a rogue user could mess you up.

So there is some desire to not implement this validation in two places and to report the validation errors from the server in the client.

Server

So on the server we define a new type that will carry the validation results.

  
 public class ValidationResponse  
 {  
   public String getStatus()  
   {  
     return status;  
   }  
   public void setStatus(String status)  
   {  
     this.status = status;  
   }  
   public List<ObjectError> getErrorMessageList()  
   {  
     return this.errorMessageList;  
   }  
   public void setErrorMessageList(List<ObjectError> errorMessageList)  
   {  
     this.errorMessageList = errorMessageList;  
   }  
   /**  
    * A general validation error not specific to a field  
    * @return The error text  
    */  
   public String getGeneralErrorText()  
   {  
     return generalErrorText;  
   }  
   /**  
    * A general validation error not specific to a field  
    * @param generalErrorText The error text  
    */  
   public void setGeneralErrorText(String generalErrorText)  
   {  
     this.generalErrorText = generalErrorText;  
   }  
   private String status;  
   private String generalErrorText;  
   private List<ObjectError> errorMessageList;  
 }  


Then the methods that accept REST POST calls and that will validate objects do something like this:

    
   @RequestMapping(value="/user.json",method=POST)  
   public @ResponseBody ValidationResponse editUser(  
       @Valid @RequestBody User user,  
       BindingResult    result)  
   {  
     ValidationResponse response = new ValidationResponse();  
     if ( result.hasErrors() )  
     {  
       response.setErrorMessageList(result.getAllErrors());  
       response.setStatus("FAIL");  
     }  
     else  
     {  
       ....  
     }  
     return response;  

In addition if you want to have an error that applies to the whole form rather than a specific field you can use the general text field in the ValidationResult above.

Web

In the form we define error spans for each field as follows. The error fields us ng-show to toggle if they will be displayed based on a hasError() method in the controller and display the content returned by a getError() method.

 
    <div ng-controller='registerController'>  
    <div class="form-group">  
      <label for="userFirstName">First name<span class="required">*</span></label>  
      <input class="form-control" ng-model="object.firstName" name="firstName" />  
      <span class="help-inline" ng-show="hasError('firstName')">{{getError("firstName")}}</span>  
    </div>  
    ...  
 </div>  

Angular Controller

As this pattern would be applied to every form, I created a base controller that the form controllers could extend to provide the validation methods.

The controller takes the resource and context (to build the URL) from its parameters when it is instantiated. The controller provides the hasError() and getError() methods as well as method for posting the updated object and checking if the result was an error.

 
 angular.module("MyApp").controller("formController",function($scope, $http, $q, object,context,resource)  
 {  
   $scope.formErrors = {};  
   $scope.context = context;  
   $scope.resource = resource;  
   $scope.object = object;  
   $scope.hasError = function(fieldName)  
   {  
     if (typeof ($scope.formErrors) != 'undefined')  
     {  
       return fieldName in $scope.formErrors;  
     }   
     else  
     {  
       return false;  
     }  
   }  
   $scope.getError = function(fieldName)  
   {  
     if (typeof ($scope.formErrors) != "undefined" && fieldName in $scope.formErrors)  
     {  
       return $scope.formErrors[fieldName];  
     }   
     else  
     {  
       return "";  
     }  
   }  
   $scope.postUpdate = function()  
   {  
    var deferred = $q.defer();  
     $scope.formErrors = [];  
     $http.post($scope.context + $scope.resource,$scope.object).then(  
       function(response)  
       {  
         if (response.data.status == "SUCCESS")  
         {  
           return deferred.resolve();  
         }   
         else  
         {  
           for (i = 0; i < response.data.errorMessageList.length; i++)  
           {  
             $scope.formErrors[response.data.errorMessageList[i].field] = response.data.errorMessageList[i].defaultMessage;  
           }  
         }  
       });  
     return deferred.promise;  
   };  
 });  

Then every controller that needs this will extend the form controller like this:

  
 angular.module("MyApp").controller("registerController",function($scope,$controller,$http,$rootScope,$location)  
 {  
   $scope.object = { }  
   angular.extend(this,$controller('formController', {$scope: $scope, object : $scope.object, context: '/MyApp', resource: '/register' }));  
   $scope.submit = function()   
   {  
     if ( $scope.object.password != $scope.passwordConfirm )   
     {   
        $scope.formErrors["passwordConfirm"] = "Passwords do not match";   
     }   
     else   
     {   
        $scope.postUpdate().then(  
          function($location.path('/registersuccessful') } );  
     }   
   }  
 });  

In this case the submit function also does some validation before sending the form content (using the postUpdate() method) to the server. When the postUpdate() completes it invokes the function for moving the URL to the success page (via the promise returned by the post method).

Conclusion

The benefits provided by the method are worth the small additional overhead. While I still find the syntax of Javascript a bit of a puzzle at times Angular is growing on me.

Monday, 23 January 2017

Working with Docker

Docker is an interesting framework for running applications within their own configuration bubble. Docker allows you to create effectively micro-VM images that you can configure with just the minimum amount of software to run a single application. The images can be built from pre-configured templates which makes setting up the image more like just installing a single package rather than building an entire machine.

Getting Started with Docker

The best place to get started with Docker is the documentation.

There are a few interesting points to note however which is:
  • Docker runs well on Mac and some flavours of Linux but on Windows you are restricted to some versions of Windows 10. I found that using centos 6.8 required an alternative installation process (see here)
  • You can run a broad range of linux distros inside Docker but AFAI can tell it isn't possible to run Windows in a docker. Although it appears there are some custom container extensions happening to make this work. https://www.simple-talk.com/cloud/platform-as-a-service/windows-containers-and-docker/
  • Dockers are really command line VMs. Forget trying to run a GUI from a Docker although clearly you could have an application inside the docker connect out to a XWindows system (but why would you?)

Docker for Development

My interest right now is in running Dockers for development. The applications I work in during my day-job (and even some I play with out of hours) require significant configuration and being able to set this up by simply downloading a docker image is attractive.

There are a couple of interesting Docker features that make this attractive:
  • You can expose your host filesystem to the docker. This means you can have a system where the artrifacts of your development build can be run pretty much directly in the docker. Without this you end up with a system where you have to run the product installer/RPM etc to install the system, configure it and then copy over the executables with the ones you just built. Docker makes this easier as you can create a docker where the executable components are links to files on the parent filesystem
  • Often multiple VMs/machines are involved in a system. You the the DB, back end server, web front-end etc etc. These can all be run as docker containers and can even be deployed into the same machine. The docker system provides a local bridge network so then no matter what machine you deploy your system on it will all interconnect.

Creating a Docker

You create a docker by creating a text file called Dockerfile and defining the actions that will occur when the docker image is created and when it is run.

In my case I was creating a Docker for a Java/Tomcat/Spring application running on Centos (as I mostly work with Centos in my day job).

So to start with we specify centos as the base image in the Dockerfile

FROM centos

Then I will install JDK 1.8 using wget so I need wget

RUN yum -y install wget

Then the following snippet gets the JDK installer from oracle and untars it and sets up the environment to run from the JDK

RUN cd /opt/;\
    wget --no-cookies --no-check-certificate \
         --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie"\
         "http://download.oracle.com/otn-pub/java/jdk/8u101-b13/jdk-8u101-linux-x64.tar.gz";\
    tar xzf jdk-8u101-linux-x64.tar.gz

ENV JAVA_HOME=/opt/jdk1.8.0_101/

ENV PATH=$PATH:$JAVA_HOME/bin

The next thing is to install tomcat. We wget the tar file, create a directory for it, untar it and ditch the .bat files. Finally we ditch the tar file.

ENV TOMCAT_MIRROR http://mirror.ventraip.net.au/apache
ENV TOMCAT_MAJOR 8
ENV TOMCAT_VERSION 8.0.37
ENV TOMCAT_TGZ_URL $TOMCAT_MIRROR/tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz

ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $CATALINA_HOME/bin:$PATH

RUN mkdir -p "$CATALINA_HOME"
WORKDIR $CATALINA_HOME

RUN wget "$TOMCAT_TGZ_URL" && \
tar -xvf apache-tomcat-$TOMCAT_VERSION.tar.gz --strip-components=1 && \
rm bin/*.bat &&\

rm apache-tomcat-$TOMCAT_VERSION.tar.gz

Now all that's left to do is to specify port 8080 should be exposed to the host so we can access tomcat and to specify that the docker should run tomcat using the catalina.sh run when it starts

EXPOSE 8080

CMD ["catalina.sh", "run"]

Building the Docker

I have been using gradle to build my application and I found there is a cool plugin for building docker images from your build. It means that you can update the docker with your built artifact during the build.

To use the plugin I load it like this in the plugins part of my gradle build file

plugins
{
    id 'com.palantir.docker' version "0.9.0"
}

Then I create a docker task like this:

docker
{
name 'tombi/abbot'
dockerfile 'src/main/docker/abbot/Dockerfile'
dependsOn tasks.war
        files 'build/libs/Abbot3.war'
}

Then I can build the docker just by saying 'gradle docker'


Running the Docker

In my case I want to access the tomcat server running inside the docker so I have to map the port tomcat listens on to a port on the host. 

Cleaning up Dockers

After a few debug runs I found I had a load of  <none> docker images. The quick way to nuke all of these is to do this:

docker rmi -f `docker images | grep "^<none>" | awk '{ print $3 }' | xargs`