Tuesday, April 23, 2013

Mastering Word 2007 .. 2013 Outline Structure and Headings


Since 2007, Word is killing me on a regular basis when it comes to chapter numbering. Many forum threads prove I'm not alone. It seemed to be pretty easy and intuitive in Word 2003 and appeared to be totally out of control since Word 2007.
I have finally figured out how it can be done right and want to let you all know (plus keep this for personal reference).

My goal is to create a document where chapters are outlined and numbered, and deeper chapters contain the numbers of their parent chapters, just like this:

1. Level 1 Chapter
blabla

1.1 Level 2 Chapter
blablabla

1.1.1 Level 3 Chapter
etc

1.2 Level 2 Chapter
etcetc

1.2.1 Level 3 Chapter
etcetcetc

Let's start with a little comparison and usability shootout of the 10-year-old Word 2003 against the latest and greatest (and if you ask me, ugliest) Word version.

Word 2003 vs 2013

The Styles and Formatting toolbar offered only these formats in Word 2003 when a new document was created:



So far, nothing is easier or better than with Word 2013 there. No heading numbers indicated, no visible structure. Maybe WYSIWYG but who knows. Even if so, it does not look like what we want to achieve. Besides offering more styles right from the start, Word 2013 is similar:


To make the chapter numbers part of the chapter headings, you would typically adjust the Heading 1 style as follows:


In the Bullets and Numbering subdialog, the Outline Numbered (sic) tab is used to create outline numbering as desired. Applying any of these formats there would immediately adjust the styles for the other Heading styles 2 thru 9, resulting in this:


Done. That's it. You are now ready to go for the content. Slight adjustments to the formats might be needed though, yet Word did most of the work generating the outline numbers for all heading quite well.

People wo didn't visit a training will most certainly fail trying to do the same with Word 2007 and later versions. The problem is that with Word 2007 the dialog was drastically reduced:


So the Outline Numbered and List Styles tabs are no longer part of the Numbering and Bullets dialog. No visible clue as to where they have gone. "What the hell" you might think, "how do I get an outline numbering done now?"

New since 2007

Microsoft introduced the Ribbons in 2007, creating the first really fundamental change in how Office is used. While many buttons and icons looked familiar, they also added the all-new Multilevel List button as part of the Paragraph group in the Home ribbon tab:


Actually, things are easy if you are starting with a minimal document and take the time to create the structure first, then the content. Suppose we have a document like this:


It is always good to have the Navigation pane visible (at least from time to time) to verify that Word "understood" your outline structure properly. Only if this tree view is a tree and has the structure according to the document as you intended, things are good. Otherwise there is work left to do.

Good and Bad Choices

Clicking the magic new button will reveal a menu like this:



Note that the red and yellow highlighting was added by me. This is to indicate good and bad choices.
When you look for an outline structure in your headings, the suggestion marked red will meet the eye first and look promising - but is one of the worst choices you can make. This is what happens if you use it:


Not quite the expected, or is it? While an outline number was added to the level-1 line which was marked before assigning the multilevel list, the Heading 1 style did not change (see preview on the gallery button in the ribbon area). It does not contain the outline numbers now, nor did the Level 1 (D) line change even though it is a heading on the same outline level. What you did just modified the single line you selected, but users probably expected this to apply for all lines of the same nature. This is where most people start shaking their heads but need to go on somehow...
... usually by selecting the level-2 line and assigning the same multi-value list style to the line, resulting in this:


Again, the Heading 2 style was not adjusted, nor was the Level 2 (E) line which is on the same level, and even worse, the numbering does not start with 1 on the new level! Word just continues the numbering across different levels now instead of restarting it for each.
The reason for this is that the outline level and the heading level are detached. You can assign a different outline level to the line now:



But this is another false friend! The outcome looks better but still has issues:


While the numbering seems to be okay for now, again this did not synchronize into the Heading styles, so it won't affect other level-2 headings. The indentation applied to 1.1. Level 2 (B) is created just-in-time by Word and is not persisted in the Heading 2 either. If you don't like the indentation, you can adjust it, but you will have to repeat this for all Heading 2 lines in your document. Certainly not the way of choice.
No need to cry yet, there is a solution. Remember the popup shown before? Let's use the item highlighted in yellow this time:



Since I know what it does it is the one I prefer for my documents. The fine difference between the two is that the top one does not include the Heading styles. This is suggested by the text "Heading 1", "Heading 2", etc. in the lower (yellow) image. Note that these text fragments are missing in the "red" button. This small clue means the styles will be included in the outline numbering pattern . If it is missing, that means the format chosen will not be reflected into the styles gallery but happen once for the current selection. NOT wanted.
Using the item marked yellow causes the headings to synchronize to the outline structure which ends in the desired result you know from Word 2003:



Note the outline numbers now added to the Heading styles in the ribbon Styles gallery, and how all lines were properly adjusted. Watch the Navigation pane which also reflects the proper structure. Done, or rather, "wow" in Microsoft-speak.

The only problem is that besides the bad placement of a bad template above a good template in the Multilevel List popup, most people do not start this way, first arranging the headings and their formatting. Typically one writes down a rough structure which is only pre-formatted, then inserts text and does the formatting later - maybe not at the very end but some time later. If you are not prepared, this will cost you hours, or even days, when you least need it.

Misleader: List Numbering Button

You might intuitively hit the List Numbering button to outline your document because it may seem to be what you are looking for. It it not. This button's actual sole use is structured lists, as in step-by-step list, bullet list, any list that is no more than a block inside your document. But certainly not your document outline.
It is a bad choice when you accidentally use it for numbering your headings.

Suppose we move the cursor to the Level 1 (A) heading and click the Numbering button, the following is the outcome - note that the Heading 1 style does not adjust to containing the outline number. The other Heading styles do not change as well. So again your changes do not reflect into the respective style which you could easily miss.


While the result may appear to be good for now (because the first heading is now numbered), note that there is no more automatism supporting you. The other level-1 heading, Level 1 (D), is not adjusted accordingly, and the Heading styles are not changing.
Now what about the headings in deeper levels? It still looks like the goal could be achieved. Move to Level 2 (B), click the Numbering button again. Of course, Word will assign the outline number 2 to the line. Even though it is a different level, it does not detect that and continues level-1 numbering:


Digging around in the menus, you may come across the same Change List Level item shown in the Multilevel List pop-up menu above (near the bottom of the menu where I have marked the red and yellow buttons). The list level is 1 by default for all lines. If you assign Level 2 from here, this is the result:




The indentation indicates that we are creating a hierarchy by now, and that the Heading 2 and outline level 2 are in sync now. They are not.
Plus, there is no way to include the parent heading number here to achieve something like "1.a" instead of only "a.". It will always only be the number or letter or whatever you define that reflects the number of the chapter inside the current level. The paragraph formatting is applied by Word just-in-time and is not stored in the Heading 2 style, same as for the numbering itself. Both is "one-shot" if you take a close look at the styles in the ribbon. It is also not applied to the other headings of the same levels - see Level 2 (E) which keeps its formatting and is totally detached from what we just did?
While this has "WRONG WAY" written all over it, most people continue creating their document to come back to this later which is no less frustrating.

Rules

There is one general rule when it comes to headings: never use the Numbering button for anything else than actual lists. In other fields it is wrong to use it, it won't do what you expect, it will just guide you into chaos. Because even if what it does may look so, it has nothing to do with the structure of your document.
And even though you do need to use List styles to achieve proper outline formatting and structure, you must not use List-related functions to get there.
The key to proper outline numbering is using exclusively the Multilevel List button with headings. Word has no good support for it because whenever you move to a line that is a heading and was created using a Multilevel List, it is not the Multilevel List button that will become highlighted but rather the Numbering button left to it. What the hell, Microsoft? This points users in the totally wrong direction again.

More Control for Power Users

One clean way out of this is creating your own List style. This is like a style template you can create in the Styles toolbox:


Click the small "expand" button in the bottom right corner of the Styles ribbon group to extend the Styles toolbox. You can also press <Ctrl-Alt-Shift-S> to toggle the toolbox visibility. In the toolbox, click the New button in the bottom left corner.
In the Create New Style from Formatting dialog, select List as the Style type. Note the changes in the lower part of the dialog. To control how levels are presented, use the Format button in the bottom left corner, and select Numbering from the pop-up menu:
.


The Modify Multilevel list dialog opens up. Click More >> in the bottom left corner to expand it so all properties are shown:


Actually, this existed in Word 2003, too, but you never had to see it. Anyway it's a good thing to know how it works.
In the level list (top left), you select the level to be edited. The remaining dialog is about that selected item.
One thing is easily overlooked here: the Link level to style dropdown box on the right. If you want to have your headings numbered properly, it is totally recommended to assign the appropriate Heading style here:


This creates the missing link. You will have to repeat this for every level though...
Here I have assigned Heading 1 to level 1 and moved on to level 2, assigned Heading 2 to it and now let's see how we can get our outline number.


See how "Heading 1" and "Heading 2" have been added to the preview area? This is where we want to get. It indicates the link to the appropriate styles.
Note that you can enforce the use of arabic numbers over roman or alphabetic numbering by ticking the Legal style numbering checkbox indicated by the right arrow. It will disable the Number style for this level dropdown box.
The Include level number from: dropdown becomes available only from levels 2 and deeper. You can use this to determine the levels you would like to include in the outline number of your heading. Only the higher levels are available here, i.e. for level 2, you can only include level 1. For level 3, you would be able to include levels 1 and 2. The list will extend accordingly.
Another important switch here is the Restart list after: checkbox and dropdown. This is the trigger for resetting the level counter. While this is of no further use on level 1, you may want to continue a numbering across all chapters without being reset to 1 by a higher level heading that was inserted. This is where you need to go for this.

If you select that Level 1 item shown in the screenshot, the result is a little peculiar though because Word has not just added the level-1 chapter number to the left of the previous value without inserting a separator. What it actually shows you here is two separate fields so close together that they look like one:


It's up to you to separate them now, e.g. by inserting a "." or a space or whatever. If two levels are using the same number style, you will need to insert something between them. If number styles are differnt, it is still possible for readers to differentiate the levels (e.g. "1b" where 1 is the level-1 capter number and b is the level-2 heading). Just click into the text box, move the cursor between the segments and insert whatever you like. The grey background indicates the boundaries of each segment:


It's a pity that in this case it is impossible to tell what segment is what level, except counting from left to right yourself. Microsoft forgot to add any means of indicating that, with tooltips or on right-clicking. Nothing of that sort here, but it still works surprisingly good and mostly as expected because Word maintains the level order. If you are editing level 3 and add the level-1 number, it will guaranteed to be the very left segment, it is not just appended to the right of the existing expression. Same, if you insert the level-2 number, that will appear in the middle.
A small annoyance here is that you will have to repeat this as well for each level, and the number of "click dropdown - select level item - watch result - insert separator" operations increases by one for each.
Also watch the Number alignment dropdown because Word tends to mix left- and right-aligned.
At least Word will make life easier when it comes to indentations. If you'd like to have all headings on the very left with no indentation at all, click the Set for All Levels... button:


This is a real timesaver. Things offered here are pretty straight-forward. Unfortunately they did not include the Number alignment box here. Still a good function.

After you are done here defining your list, it might look something like this:


It is advisable to scroll through all levels and watch the detail fields change. It is a quick way to cross-check all settings. Click OK to submit the list.
Now how do we apply it? Click the Multilevel List again and note the new section inserted there


That is what we just created. In my opinion, the caption should not read List Styles but somehow indicate that these style are your own self-made ones. I'd prefer My List Styles or the like, alas, that's not going to change any time soon.
If you want to modify anything about your list styles later, here is a secret: right-click it and select Modify. Keep this in mind. It's virtually the only way to ever get back into that Modify Multilevel list dialog shown above!


You will see that this menu item is only available for the lists you created yourself. The built-in samples cannot be changed (what a shame).

Conclusion

You should be fine with the document you have now. The headings will now work as expected.
If you want to save some work, you can download the minimum sample document that served as demonstration material for this thread here.
Have fun! Hope this saves you all some valuable hours :)
And please excuse if my English is not quite to the point...I'm not a native English speaker, much less an expert in word processing terminology - yet. Any advice on possible improvements are absolutely welcome.

See you!

Thursday, June 14, 2012

HP ProLiant DL165 G5 BIOS Salvage

Hi everyone,

here's a story that is a little more "production" instead of "private". Still, I think it was fun to do the work, and might be worth sharing.

The admins of a customer recently decided to upgrade their DL165 G5 hosting server from 4x 500GB hard disks to 4x 2TB. As a result, the server would not recognize the new disks because the controller could not handle this volume size.
HP has provided a BIOS update for this, and somewhere in the description they mentioned that all BIOS updates that were released need to be installed in the correct order first. They forgot this step and flashed the newest BIOS version right away. The software did not indicate any problems but after the successful flash process, the server was bricked. It would power up, but no boot logo would appear and the fans would stay on maximum RPM. Even after hours, nothing would change.
They moved the system to an equally-equipped machine before the BIOS update took place so at least the hosted systems were easily recovered. But the server that was used had other tasks that no server would take care of now. A replacement was needed.

So the choices were:

  • dump the entire server and buy a new one
  • buy a new mainboard from HP for 900 € (this is the only support HP is capable of)
  • buy a used mainboard with no guarantee for 500 €

As there was nothing to lose, I offered to try and unsolder the SMD EPROM chip from the board to re-flash a working firmware, then putting a PLCC32 socket where the EPROM was located to ensure that another mis-flash would not brick the server again. At least that would make it easier to replace the chip when needed.
After that was agreed with the customer, I set to buy materials required for the operation:

  • Hot air reworking station for SMD soldering / desoldering (with some PLCC-shaped caps that put hot air out of four longish jets for heating all four edges of the chip simultaneously)
  • EPROM programmer - I picked a Chinese model first but found that the software runs only under Windows 2000 and, at best, under Windows XP 32-bit, plus it was not LPC capable so there was no chance to get anywhere with the SST 49LF080A Flash EPROM
  • DIL-to-PLCC32 adapter
  • next EPROM programmer - Batronix Barlino II, a really nice German product. Solid and beautiful metal case, solely USB-powered (competitors require an external power supply in addition), works with all existing Windows flavors and comes with a software suite that is really easy to understand and handle
  • Gas-driven pen soldering iron
  • Flux dispenser pen
  • Solder wick
  • Multiple PLCC32 sockets to be on the safe side in case I'd burn the first ones
  • Testboy 
Total cost: about 300 EUR. I could have bought an SST 49LF080A chip for the unlucky case that it would not survive the desoldering but as time was rather short and suppliers did not have one right away, I skipped that and hoped for the best.

Desoldering the EPROM

Fortunately HP engineers have not put too many components around the BIOS EPROM. Otherwise, a little wrong move could have had fatal consequences. The EPROM came loose nicely after about 20 seconds of 325°C. PCB traces did not feel too happy though, some were loosened a bit while removing solder remains with the solder wick so extreme care was needed from this point on. Actually I would not recommend to use solder wick at all as it tends to melt together with the PCB soldering pads and one easily tears them off. Next time I think I'd rather use a desoldering pump instead.
Plus, I'd probably remove the BIOS backup battery before starting to avoid shorting it.

Preparations for the PLCC32 Socket

Then I put some flux around the pads to ensure that no bridges would appear between two pins later.
Fixing the socket was not quite easy as the hot air gun did not allow for too precise movement, so I fixed two pins with the gas soldering iron first, hoping that they would keep the socket in place while using the hot air gun to finish the other pins.
Of course, the cheap plastic frame on the bottom of the socket melted before any pin got a hold on the PCB so I had to get the next socket and cut the bottom spacer out. That would leave some more space for the hot air to reach the soldering pads, and not much to melt on the way. No idea how that should work in practice. These things were designed to withstand a maximum temperature of about 130°C - not really a temperature range where soldering can be done at all. But maybe I misunderstood something here?
Well, after removing the bottom spacer from the socket, there is a slight risk that the chip be pushed in too deep socket so it gets stuck and could only be removed with some violence.
I decided to add a piece of cardboard beneath the chip later which would make up enough space at the bottom to insert a chip pull tool.

Testing the Works

After fixing the socket, testing time came. I tested the contacts on the top side of the socket against the respective pin below to see if all contacts are connected - bingo, seemed okay! Also checking for bridges between neighbor pins did not give any negative result. Phew! I'd expected much more trouble in my first steps of SMD soldering.
Even though the frame of the socket had suffered a bit from the heat, it had kept its shape and a short attempt to insert the EPROM did not show any mechanical trouble.
So I let it all cool down for a few minutes, then turned my attention to the EPROM.

EPROM Maintenance

As EPROM programming devices usually have DIL sockets, an adapter is needed to provide a PLCC32 socket. It maps each DIL pin to the respective PLCC32 pin. No mapping is needed there because the pinout of the 49LF080A is compatible with standard DIL EPROM pinouts. An additional check against data sheets indicated that this was the best way to go.
The EPROM programming software was able to read data from the EPROM, and I kept a copy of it to make sure that I'd have a path back in case everything else should fail.
Writing the new image worked like a charm, too, and after roughly 75 seconds, the EPROM was equipped with a BIOS image considerably older than the one that caused the breakdown. It is a rather generic image that can be used as a starting point to apply later updates sequentially as HP demands.

Final Test

Inserted the EPROM back into the new socket of the server and prepared for the frightful power-on moment. These machines create on hell of a noise once powered on. About 15 small fans at the highest possible RPMs - don't even want to imagine what happens if you stick a finger in there by accident.
Well, so far, that was a known sight. Black screen, jumbo jet noise, but not much more. Hey, some action in the area of the RAID LED indicators on the PCB, and after about 15 seconds, the HP boot logo would appear! Yoohoo! That looked like something.
I have not known the server's behavior before, but it seems to be typical that power-up takes a lot of time until any action can be perceived.
The unit did not recognize its hard disk drives. But that was expected because there was a mix of 500GB and 2TB drives connected, and probably none of them formatted to offer anything close to a bootable OS. At least the disks were properly identified. That was enough of a proof for me that the unit had its life back and admin people at the customer site could now use it again.



Conclusion

It was quite an investment first, but in retrospect it was fun to revive the unit and find that SMD soldering is not as impossible as I had anticipated.
The DL165 appeared pretty low-end though. While it is clear that this is one of the more affordable server units, I mean, why solder an EPROM chip right to the PCB? Was that cost saving or rather intentionally forcing BIOS update victims into buying newer machines? Production would surely not have become much more expensive with BIOS EPROMs in sockets.
And while the 19-inch single-height rack housing looks pretty impressive first, that form factor comes at a price. That many small diameter fans to keep the unit from burning itself, no more than four hard disks (which are not accessible from outside with hot-plug enabled hard disk mounting frames but require shutting down and opening the unit whenever there is any maintenance to do). No thumb screws, need a screwdriver for everything. And, of course, no blade-style connector at the back but everything just like with a desktop PC. Separate mouse, keyboard, VGA, LAN, USB etc. connectors. A lot of unwiring is needed to get the unit out of its rack (the reverse way is equally painful).

Well, I hope I can get hold of one bricked DL165 and offer my BIOS rescue services. Obviously not many people dare to go that far.

So if there is anybody having a similar problem (BIOS accidents may happen with usual PC mainboards, too), just write me an e-mail and we'll see what can be done.

Thanks for reading!

Greets,
Joe

Tuesday, March 6, 2012

Reverse-Engineering a Rotary Encoder from a Panasonic VTR

Hi Folks,

recycling time - after buying a broken Panasonic NV-F75 VHS tape recorder from eBay, and no way to rescue the appliance as a whole, I stripped the valuable parts from it and now it's time to take a closer look at that Jog/Shuttle wheel that the more exclusive Panasonic models featured since the 90s. It actually consists of two nested axes, the outer one having fixed limits to the left and to the right and a center notch (shuttle wheel) while the jog dial in the center spins endlessly in clockwise or counterclockwise direction, with approximately eight "stops" per rotation as a feedback for the user.
I always loved that feature because it gave you a great way of controlling playback, allowed cueing forwards and backwards in three different speeds, and with the center wheel you could also navigate to one specific frame if you wanted, e.g. to continue recording a movie after the commercial break with frame exactness (well, nearly...)
Plus it added a professional touch to the whole device without giving it the monstrous appearance of typical studio equipment. Great thing! That would make a nice two-in-one control after all, and it appears a nice exercise to get somewhere with the Arduino microcontroller.

So here it is:





That C-shaped ring is where the shuttle ring is mounted. The center pin holds the jog dial that moves freely around its axis inside the shuttle ring.
View from the back - the two latches left and right of the center are not actually contacts with electrical meaning. I assume they mainly serve for fixing the unit properly on the PCB where it is mounted.




The 8-pin connector that I soldered to the unit is meant to adjust the contacts to fit the encoder's custom pin spacing to match a standard breadboard spacing. Figuring out the pinout from outside seemed a little hard, so I decided to open the unit and take a close look inside.
It is quite easy to open it. Just pry open the four clips on the back as indicated here and the unit comes apart - the two latches left and right from the center may be a little tricky though:




It consists of 5 pieces in total:




From left to right:

  1. backplate and center axis
  2. rotary encoder for jog dial
  3. interconnect place with 3 conductors directed to the bottom for the jog dial and 6 pointing to the top for the shuttle wheel
  4. shuttle wheel ground plate (contacts on the backside, see below)
  5. top ring to hold it all together and limit the range of motion for the shuttle wheel

Here are some closeups:










There is a lubricant across all contacts that I didn't want to remove to keep the unit in good shape. What we see here is part of the jog dial encoder. All golden surfaces are interconnected. Still there are three tracks. The center track is ground, and as the two other (partially covered) tracks are running parallel, the encoding trick must take place on the interconnect plate.



The interconnect plate. On the left, we see six contacts that face to the front (to touch the bottom of the shuttle wheel - we'll see that later). The right side offers three contacts. Remeber the layout of the encoding wheel? We can see here that the left (ground) and middle contact are on the same level while the right contact is a little longer. That means that in comparison to the middle contact, the right one will connect to ground either later (in a clockwise rotation) or earlier (in counterclockwise rotation) than the middle contact. That gives a decent way of figuring out which direction the jog wheel turns. I'll discuss that later in detail.





Bottom side of the shuttle wheel. That looks like a binary encoder indeed. The inner ring seems to be the most significant bit (MSB) as it has only two different states from one end to the other (left: off, right: on). The further outside the rings are, the more frequently they change their on/off states.

Guessing from the layout of the traces on the interconnect plate, the left four or five contacts (seen from the top of the unit) probably deal with the shuttle wheel whereas at least two of the right contacts deal with the jog dial. One pin is probably the common ground line.
Using a multimeter, I found out that the pinout seen from the direction shown in the photo is (from left to right):

Shuttle Bit 3 (MSB)
Shuttle Bit 2
Shuttle Bit 1
Shuttle Bit 0 (LSB)
Common Ground
Jog Dial Middle Contact (I'll call that A from now on)
Jog Dial Right Contact (calling this one B from now on)

Examining the Jog Dial




This closeup shows the encoding magic. The left of the three connectors is ground, and the middle one is alternating between ground and NC as the dial is turned. Same goes for the outer pin but that one catches the ground / NC status a little before or after the center pin. This relation in timing lets us determine the rotary direction eventually:
Turning the jog dial clockwise would cause the center pin to change first from NC to ground or vice versa. As the outer pin is a bit longer, it takes more time for it to reach the same connection state. Likewise, when turning counterclockwise, the outer pin reaches ground first, and the center pin shortly after that.
We can draw two bits from there. When any change is detected, we need to compare the previous set of bits to the current set. Depending on the direction, the sequence of values will give us a clue. I'll discuss that in detail further below.

Examining the Shuttle Wheel

Now that the ground wire and the four bits for the shuttle wheel data are known in the pinout, it is time to connect the whole thing and link up some LEDs to determine the order of values we get for each position of the wheel:



I prepared a breadboard with six LEDs and set up the pins to match the ones on the encoder unit.




The left four LEDs are the bits from the shuttle wheel (left = MSB, then bits 2, 1, 0). The other two LEDs are what I have called A and B earlier, and they reflect the current jog dial activity.
One might have derived the values from the encoder backplate, but I preferred to try to get the most accurate results. Why waste time guessing?
This is what I found out:
 


See how nicely this pattern repeats on the backplate of the shuttle wheel? Only one odd thing I found: the shuttle is supposed to have a center position and the same number of positions to the left and to the right, but that would require an odd number of states. In fact, I found 16 different states, which means that the center position is not actually the center. There should be two values indicating center, but the center notch is clearly linked to the value 12. Well, the value 4 appears only a very short time when turning right from the center notch, so it would probably be good to interpret both 12 and 4 as "centered".

Logic Behind the Jog Dial

We still have to figure out how to detect clockwise / counterclockwise motion on the jog dial. The sequence of bits is like this (as measured on the breadboard):




So rotating clockwise will give this sequence: 2, 3, 1, 0, 2, 3, 1, 0 etc.
Counterclockwise results in: 1, 3, 2, 0, 1, 3, 2, 0 etc.
The orange arrows just indicate where the pattern repeats. This is to cover the sequence "0, 2" for clockwise and "0, 1" for counterclockwise rotation that one might otherwise miss.

Now we don't want to sample four values until we are sure about the direction, so let's take a look at all possible combinations of one value followed by the next, because in most cases just two samples are enough to give a clue.
For instance, if we look at the clockwise sequence above once more, there are four possible pairs contained:

  • 2, 3
  • 3, 1
  • 1, 0
  • 0, 2

Same for the counterclockwise list:

  • 1, 3
  • 3, 2
  • 2, 0
  • 0, 1

So from the twelve possible sets, we can at least identify these eight doubtlessly:



Value1 always preceeds Value2 in time, so in order to measure a movement, we need to have a "previous" value buffered to compare with the current measurement. We have four states that clearly indicate a clockwise motion because these four sequences appear only as a subset of the clockwise sequence shown above. Same goes for the counterclockwise sequences of which we have also four. Eventually there are four states that are indeterminate because these sequences appear neither on the clockwise nor on the counterclockwise original sequence. If we measure something like this, this should just cause a repetition of the last clearly identified motion.
I think the easiest way to manage values from the jog dial is a single value that either decreases (when rotating counterclockwise) or increases, like a slider control in current computer operating systems.
The following "jog states" we might detect (again, this presumes we have a "previous" state = State1 and a current one, State2):



Read the table like this:

  • for 1st line: if there was no known previous state, and the current state indicates clockwise movement, then increase the value
  • for 3rd line: if the previos state was a clockwise rotation, and the current state is indeterminate, just act like the jog dial is still turned clockwise, and increase the value
  • for 5th line: if the previous state was clockwise rotation, but the current one is counterclockwise, decrease the value

I have made some notes during my breadboard experiments. Most of it is covered above in nice Excel tables, but this also shows the controller pinout. As you can see here, there are only seven positions associated with the "left" side of the shuttle wheel (i.e. if it is turned far right, that means it has position 8), while there are eight for the "right" side, leaving one that clearly indicates center position (12). I'll interpret the value 4 as "center", too, because it is very small compared to the range of motion, and this balances the number of values on both sides.


That's it for now. Soon I will try to use this in combination with an LCD display on the Arduino Duemilanove. Might take a while because that C language keeps driving me nuts. Once there is something to be shown, I will post it here of course!

Thanks for reading! CU soon!



Follow-up: Arduino Sketch


As requested by Fentronics, here is the Arduino sketch I used to read both components of the device, the rotary encoder (jog wheel) and the Gray-encoded shuttle wheel:

// pinout:
const int LED = 13;
const int JOG0 = 7; // digital 7
const int JOG1 = 6; // digital 6
const int SHUTTLE0 = 2; // digital 2
const int SHUTTLE1 = 3; // digital 3
const int SHUTTLE2 = 4; // digital 4
const int SHUTTLE3 = 5; // digital 5

const int ROT_CW = 1;
const int ROT_CCW = 2;
const int ROT_NA = 0;

byte prevJogCode = 0;
byte prevJogState = ROT_NA;
int jogValue = 0; // value of the jog wheel

// jog state to direction translation
const byte jogStates[16] = { ROT_NA, ROT_CCW, ROT_CW, ROT_NA,
                             ROT_CW, ROT_NA, ROT_NA, ROT_CCW,
                             ROT_CCW, ROT_NA, ROT_NA, ROT_CW,
                             ROT_NA, ROT_CW, ROT_CCW, ROT_NA };

byte shuttleValue = 0; // value of the shuttle wheel
byte prevShuttleValue = 0;

// gray to binary translation
const byte shuttleValues[16] = { 8, 9, 11, 10, 14, 15, 13, 12, 4, 5, 7, 6, 2, 3, 1, 0 };

void setup()
{
  pinMode(LED, OUTPUT);  //we'll use the debug LED to output a heartbeat
 
  pinMode(JOG0, INPUT);
  pinMode(JOG1, INPUT);
  digitalWrite(JOG0, HIGH);
  digitalWrite(JOG1, HIGH);
 
  pinMode(SHUTTLE0, INPUT);
  pinMode(SHUTTLE1, INPUT);
  pinMode(SHUTTLE2, INPUT);
  pinMode(SHUTTLE3, INPUT);
  digitalWrite(SHUTTLE0, HIGH);
  digitalWrite(SHUTTLE1, HIGH);
  digitalWrite(SHUTTLE2, HIGH);
  digitalWrite(SHUTTLE3, HIGH);

  Serial.begin(9600);
}

void loop()
{
  // read jog rotary encoder (2 bits)
  byte thisJogCode = (digitalRead(JOG1) == LOW ? 2 : 0) +
                     (digitalRead(JOG0) == LOW ? 1 : 0);

  // compare to previous
  bool jogChange = (thisJogCode != prevJogCode);
  if (jogChange)
  {
    // determine current direction from the states table
    // using the previous and current value
    byte jogState = jogStates[prevJogCode * 4 + thisJogCode];
  
    // if the new state is NA, continue into the same direction
    // as last time
    if (jogState == ROT_NA) jogState = prevJogState;
  
    // increase/decrease counter
    switch (jogState)
    {
      case ROT_CCW: jogValue--; break;
      case ROT_CW: jogValue++; break;
    }
    prevJogCode = thisJogCode;
    prevJogState = jogState;
  }
 
  // read shuttle bits
  byte gray = (digitalRead(SHUTTLE3) == LOW ? 8 : 0) +
              (digitalRead(SHUTTLE2) == LOW ? 4 : 0) +
              (digitalRead(SHUTTLE1) == LOW ? 2 : 0) +
              (digitalRead(SHUTTLE0) == LOW ? 1 : 0);

  // convert to binary (0 = far left, 15 = far right)
  byte shuttleValue = grayToBinary(gray);
  bool shuttleChange = (shuttleValue != prevShuttleValue);
  prevShuttleValue = shuttleValue;
 
  // announce to serial if there are any changes
  if (jogChange || shuttleChange)
  {
    digitalWrite(LED, true);
    Serial.print("Shuttle: ");
    Serial.print(shuttleValue);
    Serial.print(" Jog: ");
    Serial.println(jogValue);
    digitalWrite(LED, false);
  }
}

byte grayToBinary(byte grayCode)
{
  for (int i = 0; i <= 15; i++)
  {
    if (shuttleValues[i] == grayCode) return 15 - i;
  }
  return 0;
}


The code is quite primitive. It would be much cleaner to use interrupts so the processor only has something to do on any bit change instead of testing each bit thousands of times per second. Well, this is only for testing so I left it at this.
The code will measure all pins and derive the value information from their states. Whenever a state change is detected in one of both components, a line is written to the serial interface reflecting both values, and the LED (pin 13) is flashing.
The jogStates and shuttleValues tables are directly reused from the tables shown in the original post.
Feel free to ask if you have any questions, and have a lot of fun :)

This is how to wire it up - couldn't be easier, really!


Thursday, January 6, 2011

Fixing WMIDiag to run on Windows 7 and Windows Server 2008 R2

Hi everybody,

after having some trouble on my workstation with Acronis backup software, it seems that the root problem is somewhere inside WMI. Microsoft has created the WMIDiag tool to check all aspects of WMI and log the results in a large file. Unfortunately, it won't run "as is" on any OS newer than Vista SP1.
I found a hack though to enable the script to run on my Windows 7 Ultimate x64. In case you need the tool, you might find this helpful.

What you need


WMIDiag self-extracting archive (download here)
a text editor that is capable of showing line numbers, Notepad++ is a nice and free tool for this

Steps to enable newer OSes in the script


The WMIDiag main part is a very large VBScript that is pretty easy to modify. Extract the files to any folder and then open the file WMIDiag.vbs in the editor.
Move to line 147 to see the "known" operating systems. We need to insert two lines at line 167:

Const cWindows2008R2 = 262144
Const cWindows7 = 524288

Now we have defined internal IDs for Win2008R2 and Win7, and it's time to use them. Go to line 10776 (should read "Case Else"), and before that, insert the following block:

                Case "6.1" ' Windows 7
                     If RunTimeEnvironmentInfo.IsServerOS Then
                        GetOSVersion = cWindows2008R2
                        RunTimeEnvironmentInfo.OSBrandVersion = "2008 R2"
                        RunTimeEnvironmentInfo.ProductFullName = "Windows 2008 Server R2 - No service pack - " & RunTimeEnvironmentInfo.ProcessorArchitecture
                        RunTimeEnvironmentInfo.ProductShortName = RunTimeEnvironmentInfo.NTBuild & "_.SRV.RTM"
                     Else
                           GetOSVersion = cWindows7
                        RunTimeEnvironmentInfo.OSBrandVersion = "Windows 7"
                        RunTimeEnvironmentInfo.ProductFullName = "Windows 7"
                        RunTimeEnvironmentInfo.ProductShortName = "VISTA.CLI"
                     End If

                     If RunTimeEnvironmentInfo.Is64 = False Then
                         RunTimeEnvironmentInfo.ProductShortName = RunTimeEnvironmentInfo.ProductShortName & ".32"
                     Else
                        RunTimeEnvironmentInfo.ProductShortName = RunTimeEnvironmentInfo.ProductShortName & ".64"
                     End If

You should find the "Case Else" on line #10794 or #10795. You may insert blank lines to make the script look nicer, but there is no syntactical need for them. Now save the file.
This hack is not perfect - Windows 7 will be identified as "VISTA.CLI.32" or "VISTA.CLI.64" depending on the OS bitness, but I think this better not change because it might cause side-effects on the tests that are run. You will find this string in the report file and the Excel sheet that is created - never mind. You know from a lot of other indicators that it's actually not Vista.
Finally, move to line #17270 and change it as follows:

               Case cWindowsVistaRTM, cWindowsVistaSP1, cWindowsLonghornRTM, cWindows2008R2, cWindows7


Running the script


  • I'd recommend running the script in a shell instead of just double-clicking it as inside the shell you can see the script's progress. So, open the start menu, enter cmd in the search box and hold both Ctrl and Shift while clicking the Command Prompt entry shown in the results list. This will ensure that the command prompt is started with administrative privileges which you will have to confirm by a UAC prompt that opens right after you clicked.
  • Once the command prompt is open, enter Cscript.Exe /H:Cscript to make CScript your default script environment.
  • CD to the directory where you put the modified WMIDiag script
  • enter wmidiag to run the script

Good luck!

Well, now I can start digging the output for hints on what is actually wrong here :o|

2013-04-23 Version 2.1 Bugfix

Hi all,

after Microsoft updated the WMIDiag script to version 2.1 to include Windows 7 and 2008 R2 (well, about time now that Server 2012 and Windows 8 are out!), they included a bug again for our delight.
The structure of the statistics CSV file that is rendered in the TEMP directory by default is missing two columns. Therefore, the Excel output will not be okay once you imported the CSV file into it.



I think I found the missing columns. In Excel, it is the columns AD and AE. The CSV file is missing them, so everything right to the column AC is shifted left by two columns.
There are two ways to fix this:

  • modify the Excel sheet and remove the columns highlighted before importing the CSV
  • importing the file and then shifting everything in the line to which you imported from AD:CM two columns to the right

Shifting can be done easiest by selecting the range from AD thru CM, then using the clipboard to mark the selection as to-be-cut (with Ctrl-X), then placing the cursor into the column AT and then pasting (Ctrl-V). Please be sure to mark the cells of only the row you importeed, not the entire table with column headers etc.
It's a dirty hack, I agree, and it won't bring you back the information of how the WMI repository size changed in relation to before the script was run. Sorry, but I'll look for a fix.


Have fun!

2013-04-24 Version 2.1 Final Bugfix

Guys, I figured it out! There is an inactive line of code that should obviously be active. This circumstance causes the disk space measurements to take place only after the WMIDiag process, not before, even though these two additional values are expected in the Excel sheet

The problem is in line #1317 of the WMIDiag.vbs file. You can easily spot it by searching for "BEFORE" (with the quotation marks and in capital letters) with any editor. The first matching line is this one:

    ' boolRC = CheckWMIRepositoryFiles (objLOGFileHandle, "BEFORE")

To activate the line, remove the apostrophe character ( ' ) before boolRC. Please do this only if the line reads exactly like what is shown above. There are more lines matching the search expression, so be sure to hit only the first one of them.
The structure of the CSV output then matches the XLS columns perfectly again :)

You can get the fix from here (it is a ZIP archive containing all files of the original WMIDiag.exe, except for the fixed .vbs file)

Hope I could help some of you.

2013-06-12 Version Adjusted for Windows 8 + 2012

Based on the VBS script from 2013-04-24 (see above), I have added OS version constants and code to identify Windows 8 and Windows Server 2012, however I don't have any Windows Server 2012 installation here, so I could not properly test that.
For Windows 8, a whole lot of errors are logged in the C:\Windows\WBEM area. Don't know if that is only my system (it's a virtual machine I set up when the first free beta of Windows 8 was released).
Please check it out and let me know if you feel anything is wrong about it.

Get your ZIP here

Regards,
Joe

2014-06-30 Version Adjusted for Windows 8.1

Based on the VBS script from 2013-06-12 (see above), I have added OS version constants and code to identify Windows 8.1. Internally it has version "6.3".
SP1 recognition has been added, too, although it is not clear at this time whether it will work properly. Likewise, it is still unknown when and if Windows 2012 Server will switch its version to 6.3. I think that is likely to happen if there will ever be a 2012 R2 edition. The VBS script will not recognize 6.3 server products for now however because there are too many uncertainties. I hope that is okay for all of you.
Thanks to Chris for notifying me about the 8.1 problems :)

Get your updated ZIP here

Regards,
Joe

Monday, October 11, 2010

[Amiga] A2000 Battery Recovery

This is another repeated article from www.amiga.org.

Hi people,

in case someone needs to repair some damage done to the Amiga 2000 mainboard by a leaking battery, this is the right place for you.
Found that A2000 on eBay a few days ago. It was sold as defective and would not power up. Obviously, the seller didn't know too much about the computer, but I took the risk and got the item for about 45 EUR. Not too much loss if it was irrepairably broken.
It's a fascinating machine, pretty large and with a lot of space inside, so I won't ever need to think about heat dissipation like in my two A3000 models. In comparison, they are pretty crowded and less maintainable. The A2000 features the largest PCB of all Amigas (it's actually huge, about 4 times an ATX mainboard), and except for Agnus who is PLCC, all custom chips are still DIP-shaped like in the Amiga 500. A lot of Zorro slots provide great extensibility, and I was happy to find a Kickstart 2.0 ROM in there. Not much more though, no RAM expansion, no hard disk drive or anything else.
I have made an attempt to repair it today as this was another battery leakage victim like most of the Amigas who boast an RTC. The battery has done some bad-looking corrosion to the mainboard, and as the CPU socket is quite near to the battery, it was affected, too.

Tools needed to do this repair:

  • soldering iron (mine is an Ersa Multitip 15 Watts, about 25 years old)
  • some solder wire
  • unsoldering tool (I used a cheap one-shot-and-reload vacuum pump with a silicon tip)
  • multimeter to check that the PCB connections are still okay
  • in my case, a new 68000 socket (DIP-64)
  • (later) a button battery (CR2025 or CR2032) and an appropriate clip
  • (later) a diode for the new battery to prevent destructive recharging attempts by the board
And here's what I did:

  • completely disassembled the A2000 to find a 5,25" drive inside that does not connect to the board directly. Obviously some freak has converted a former external drive into an internal one, also keeping the adaptor PCB and a lot of cable straps, sigh... the connector cable needs to go out of the case to the external floppy port... ah well, that's going to be a different thread. I don't think I can bear this for long :-D
  • removed the mainboard from the case and cleaned it a little. Some big flakes of dust have accumulated there over the years
  • removed the battery (sorry, no pictures here) and thoroughly cleaned the PCB in that area. I noticed that the PCB is pretty delicate when trying to unsolder. The solder mask becomes damaged when exposed to too much heat for too long (and in this case, I think it is lots shorter than usual), and probably one would easily kill leads unless being extremely careful. Maybe the board's age adds to it.
  • checked damage done by the corrosion. Nothing seemed to be actually broken and no leads seemed disrupted by the corrosive process. I sure hope it does not continue in the future.

The old battery after removing. I can't understand how Commodore could be so stupid as to place batteries directly on the board with no socket. Sigh... well, that seems what everybody did those days.




Notice the dark spots left by the corrosive. It has come pretty far and even dug along under the battery lead. The CPU socket shows traces of corrosion, too. See the greenish pins 1 to 6. I think this is the main reason the A2000 has failed (probably no good contact anymore)

Different angle
  • I decided it's hopeless to clean the socket, plus I wouldn't get a chance to see if anything is broken beneath the socket, so I removed it completely. As unsoldering this item without damaging the board is near impossible, I broke the socket frame and pulled the plastic parts of it away from the board, leaving only the metal pins.

68000 socket, no plastic frame
  • then I unsoldered all the pins one by one while pulling them away with a pair of pliers on the other side. That worked pretty well but left the soldering eyelets closed in most cases.

Socket debris
  • to make unsoldering easier, I put some solder on all the eyelets so they would heat up more quickly on both PCB sides
68000 socket eyelets prepared for de-soldering

  • after unsoldering, a visual check of the board against outside daylight offered no obstructed eyelets:

Shiny!
  • this was a good time to do some measuring on the leads in the area affected. As it seems, all are fine, no leads broken. I scratched the masking paint from the place where the battery cathode was placed to see what has happened there. See the bluish touch of that beastly stuff?
Socket gone - blue traces of battery sludge beneath the masking paint

  • now I inserted the new 64-pin socket and fixed it
New 68000 home from the PCB bottom


68000 replacement socket top view


Mind the copper lead I found where the battery was. Obviously there was no actual damage although the lead may have been thinned out considerably.

68000 in place again

68000 edge view

After connecting to the PSU and floppy, I carefully started the machine for the first time since I received it. The Kickstart screen came up and first attempts to load disks were successful! Yippieee, day saved! :-)

There are some things to do though. As I don't have a button battery and socket handy, I will have to do that replacement later. Maybe I'll post some photos about that, too.

Hope you liked this A2000 revival story!

Have a nice day,

Joe