Category Archives: Bits and pieces

MC34063: A tough lesson

As a keen electronics hobbyist, I have designed some 50 or so PCBs to date. In each instance where a switching regulator is required, I’m typically reaching for one of two options: Where efficiency isn’t important – the trusty old LM2596, or when efficiency is required, I’ll be using a design from Linear Technology with synchronous regulation.

On my last two boards however, for reasons I am myself not entirely sure of (cost perhaps?) I used an MC34063. It’s been with us since the dinosaurs roamed the earth, and is unsurprisingly very primitive. It should have been designated to the dustbin of history, but thanks to the internet and the renascence of electronics in the hobbyist space, it has made an aggressive comeback, and for a simple reason: It’s dirt cheap.

My MC34063 was deployed on the PCB with the above circuit, lifted unchanged from the datasheet. It just so happened that I need 5V at 500mA max, from a 24-28V source. Perfect. What could possibly go wrong?

There is one very important thing we must consider when using this chip: It has absolutely no built-in thermal protection. The above circuit does have over-current protection, but this does not offer any protection from sustained short circuits. In many cases that isn’t a problem, but on this board it was.

From looking at the photo, we can see that there’s quite a bit of burned out stuff, making it a little difficult to piece together exactly what happened. Fortunately it all unfolded before my very eyes. The problem started with something that was nothing to do with the MC34063. See those two rectangular capacitors?  One of them is particularly toasty indeed.

That capacitor is an AVX “TAJ” series 330uF 10V tantalum. It had developed an internal short circuit which caused the MC34063 to gradually heat up, eventually reaching a point where its internals melted, then becoming a short circuit its self.

Once the MC34063 became a short circuit, the 25V input voltage surged straight through to the 5V secondary, bear in mind that, that voltage is coming from a bank of large lead acid batteries.

Both pairs of batteries were protected with battery fuses, but those were 15A a piece, as this is a very high power setup, also on the PCB was a 30A maxi blade fuse. Surely one of those would have blown? Nope. When silicon melts to the point of becoming a short circuit, there is typically still a few ohms of resistance, which in this case was not enough to blow any fuses.

What happens next? BOOM! The short circuiting of the MC34063 unleashed 25V @ ~40A of potential at that shorted capacitor, which promptly exploded, ejecting a significant amount of fire and hot gasses in the process. In the picture you can clearly see the internals of it have become a melted blob of metal, transforming it into a very effective short circuit.

The last phase of destruction was the MC34063 its self burning to a cinder, as it is now the weakest part of the circuit, doing significant damage to the PCB in the process.

It’s at this point that you start recounting exactly what is attached to the 5V rail, because it is likely now toast. The tantalum capacitor must have briefly been open circuit because all 10 ICs fed from the 5V rail were completely destroyed, as well as all of the chips on a second PCB also fed from this regulator, requiring hours of rework to replace them all. Just as well there was nothing expensive connected to it.

Lessons learned

  • When using an MC34063, or anything else without built-in protection – short out its output for a few minutes and see what happens. If you find yourself staring at a mess like the above, sort it out. Don’t ever assume it won’t happen.
  • In cases like this where the system is fed from batteries, protected by large fuses – add a second smaller fuse i.e. 500mA before small circuits like this.
  • In my case I have ditched the MC34063 and replaced with with a Wurth 173010542 7805 switching drop in replacement. It gets me a 5V output with 90% efficiency, over-current and over-temperature protection. Not cheap, but when you are talking about stuff that could start a fire…

An easy way to mount DS18B20 temperature sensors

 

One of the biggest advantage of these sensors over I2C sensors, is that you can mount them almost anywhere. That having been said, I’ve never quite managed to come up with an elegant solution, particularly when attaching to a heatsink (for cooling applications).

Typically I find myself drilling 5mm holes in pieces of aluminum, then stuffing the sensor in that hole, or using small metal clips, which aren’t always reliable.

One solution I looked at using the aluminum heatsink clips from vintage TO-92 transistors i.e. 2N3403 and 2N4425. These are absolutely perfect but unfortunately the clips aren’t purchasable without the transistor. Sadly these parts are no longer in production and becoming increasingly rare. Destroying them to scavenge thier heatsink clips is a little senseless.

Some old TO-92 transistors came with rather nice heatsink clips

Without wanting risk the wrath of the world’s remaining Ham Radio enthusiasts… What other options are there?

I recently had the idea of using ‘Yellow’ (6mm) ring terminals with 3.2mm holes:

Perfect! All I had to do was remove the plastic band, cut the crimp and open it a little, add a little heatsink compound (to be pedantic), then gently crimp the sensor in place with pliers.

This has turned out to be a robust and inexpensive solution, as those terminals are made of copper, they conduct heat very effectively. I wish I had thought of this a decade ago.

Putting a little heatshrink over the final assembly makes for a good finishing touch.

A simple low battery detection circuit with hysteresis

I recently found myself needing a simple circuit which could detect a low battery condition of a sealed lead acid setup, but also with a hysteresis function i.e. don’t re-enable the output until the battery voltage rises to a certain threshold.

The internet is practically exploding with low voltage detection circuits but many are quite complicated with exotic ICs and other fussy details.

Geez man. All it takes is a single comparator and a two resistors (three for hysteresis).

lbatt

Okay so my circuit has a little more, that is because making something that is actually useful requires a bit of extra stuff.

With the above component values it will cut out at 11.2V and re-activate at 12V, which is good for most sealed lead acid batteries. There is also second comparator – this is purely acting as a logic inverter, because I needed a negative logic output. If you don’t need it, leave it out. One of the cheapest and most available comparators – the LM393 has two units anyway, so this works out well.

The main guts of the circuit is R1, R2, R3 & U1A. R4 & R5 are a simple voltage divider to get the input voltage inside of the 5V operating range of the comparator. R6, R7 R8 & R9 should be left as is.

The math

Because I’m using fixed resistors, I’ve worked backwards, from a ‘components first’ approach, simply working out the formula for the circuit then plugging a variety of E24 resistor values in until I got what I wanted. I find this easier than working from a ‘results first’ approach i.e. starting with the desired voltages, to then being told by your workings you need a whole bunch of resistor values that don’t exist!

  • VCC (Constant – 5.0): The output of the 78L05
  • VL (Constant – 0.1): The voltage the LM393’s output transistor can pull down to. Yours may vary. The expression containing this term can be omitted if you are happy to call it zero.
  •  VIl: The low battery input threshold voltagevil
  • VIh: The high input threshold voltage i.e. re-enable output when voltage reaches this level

vih

If you wanted to adjust my thresholds, assuming a 12V setup, focus on R1, R2 & R3. Leave R4/R5 as is. If changing to a different voltage / type of battery, then R4/R5 need to be adjusted to bring the voltage at pin 2 within a 2-3 volt range.

Making use of recycled Xilinx XC9500 CPLDs

If you happen to be producing boards which use Xilinx’s long discontinued classic 5V CPLDs which are purchased as scrap from the far east (which I hope you are not); You may have found that getting quality samples is not so straight forward.

The situation is not so bad for smaller devices, but for the larger ones, it’s tough. One of my projects (8OD) is stuck with the XC95216. Being a 100% 5V design with a swag of 5V bidirectional I/O pins, converting to a modern 3.3V device is completely out of the question.

Without the spare time or willingness to adapt the design to an inevitably ridiculously expensive alternative; I have been dependent on purchasing recycled chips from the far east (typically sold on eBay or AliExpress).

In terms of what arrives in the post, it’s a mixed bag. I’ve had perfect genuinely new batches, and other batches which are in poor physical condition (i.e. scratched, pins bent / missing).

To frustrate matters further, the best (absolutely perfect) batch I received then prompted me to make a second purchase from that same seller. But upon arrival of that parcel, I quickly see that it was sent from a different address, different packaging. Surprise surprise… Some were clearly scrap, and most of them were dead.

Here is a sample of the kinds of errors I find when I assemble boards when dead chips:

Completely sodding’ dead

When dealing with properly dead chips we sometimes see an error like this from iMPACT:

PROGRESS_START - Starting Operation.
INFO:iMPACT:583 - '1': The idcode read from the device does not match the idcode in the bsdl File.
INFO:iMPACT:1578 - '1': Device IDCODE : 00000000000000000000000000000000
INFO:iMPACT:1579 - '1': Expected IDCODE: 00101001010100010010000010010011

I have also seen iMPACT spit out messages like this when attempting to connect:
manydevs

Less than healthy

I have seen quite a few that sort-of work, but fail on the identification stage, like this:

Identifying chain contents...INFO:iMPACT:1585 - '0':The part appears to be of type xc9500, but could not be identified correctly .
'0': : Manufacturer's ID = Xilinx unknown part, Version : 1
INFO:iMPACT:1111 - Can't locate bsdl file xc9500.bsd.

This is quite a curious error, as I have had chips, both from the same batch, identical markings etc where one identifies OK, but the other has a bit or two twiddled (i.e. version as shown here).

Avoiding wasting your time with dead chips

I have spent a lot of hours checking soldering, voltages, JTAG signals on my scope etc, all to no avail. I do not know what is involved in recycling these chips but whatever the process, a crapload of them don’t survive it.

Quite how so many end up dead leaves one to ponder, because from my own experiences, they are pretty robust. I have some XC95216’s that have been carelessly soldered/de-soldered 5 times or so by myself, zapped with large electrostatic discharges and even those survived! Perhaps these chips are typically removed from equipment with a propensity for suffering lightning strikes? Are they de-soldered with a flame thrower?

A quick google image search for “Guiyu” gives us a hint of what this business is like. My own guess it that they are killed with excessive temperatures during de-soldering.

Rule of thumb seems to be, if it can be successfully programmed with iMPACT, it’ll work. I have not yet found one that then went on to fail the burn-in test.

And on that note, I took the time to build a simple rig to weed out the duds:

DSC_7403

It’s a blank PCB with power, decoupling and JTAG components fitted. I then use a small clamp to press the CPLD onto its footprint on the board, with a block of polypropylene and a layer of adhesive felt to ensure even pressure. To keep it extra high-tech – I’ve also got a pad of post-it notes underneath.

As much as this may not appear to be a reliable mechanism, it most certainly has proven to be. I happened to have preserved a tray of known-good / known-bad chips and when I tested them with this, the good chips – even those weren’t very well cleaned up (i.e. still some solder on them) verified perfectly in this rig.

Last but not least:

If you end up with a bunch of dead chips, use buyer protection to get your money back.

This is a lot easier on AliExpress than eBay

At the very least we may be able to entice recyclers to be a little more cautious.

Getting rid of that darn Device Information dialogue in Xeltek’s SuperPro programmer software

A little while back I purchased Xeltek’s SuperPro 610P Universal programmer.

It has the odd quirk, but overall it’s done the job. There is one thing however that has always irritated me about this product – This damn thing:

sp0Every time you start their application, or change device, you are prompted with this absolutely f–king useless dialogue, having to dismiss it every time, worse still, it has no OK or Close button. Even more annoying, there is no option to disable the displaying of it in the first place.

Hell, even if there was any useful information on it, that doesn’t mean I want to see it every single time I use the SuperPro!!!

I contacted Xeltek’s customer support about that, they had me go to the trouble of sending my invoice and serial number to them to prove that I in fact had actually paid them a sum of money, and then promptly did absolutely nothing about it, other than tell me that it could not be disabled.

Despite how simple it would be to even change the software to provide an option to disable it, repeated requests to do so were ignored.

Righty. Time to do something about this. 30 minutes behind IDA later we’re onto it. Quickly I can see it is written on the very same tech I cut my own teeth on: Microsoft Foundation Classes (MFC).

Given this, it’s pretty likely that we’ll see a call to _AfxPostInitDialog() at some point during the displaying of a dialog.

Let’s put a breakpoint in there, and bingo! Hop back up the stack a little, and there I find the offending instruction:

sp1

 

The highlighted instruction is in code written by Xeltek, and calls a function which displays that dialogue both when the application starts and when the device type is changed, but not when the “Dev. Info” button is pressed (in the unlikely event I actually want to see that bloody useless dialogue).

sp2

So all that needs to be done is remove it.

In the current version at the time of writing (the version dated 07/21/2016) that instruction (opcode 0xE8) and its 4 byte operand is physically located at 0x3373F in SP6100.exe. Replace it with 5 NOP (0x90) instructions, and we’re good.

Now that dialogue is only displayed when the “Dev. Info” button is clicked, which is all I ever wanted to begin with.

Feel free to contact me if you want the patched EXE!

Configuring a Cisco 877 for IPv6 on Snap/2Degrees

Recently while staying with the folks in New Zealand, I read that (their) consumer focused ISP – 2Degrees (Formerly Snap Internet) is actually offering IPv6 connectivity to customers, no strings attached!

Although not news, this is a pretty significant development for the New Zealand Internet Service Provider market, with almost every other provider very much heads in the sand on the matter.

IPv6 Adoption in New Zealand (Courtesy Google): Not impressive
IPv6 Adoption in New Zealand (Courtesy Google): Not impressive

Being a nation with a small population and in possession of a fairly reasonable stock of IPv4 addresses, it’s not surprising the countries services providers have been procrastinating.

But anyway, the important question: Does it actually work?

A Cisco 877 I left here a number of years ago ought to be up to the task.

First, let’s get IPv6 turned on:

Router(config)#ipv6 unicast-routing
Router(config)#interface Dialer0
Router(config-if)#ipv6 enable

And now the important bit – lease an IPv6 prefix from Snap using DHCP and prefix delegation, and name it ‘snap-provided-prefix’ (As an example):

Router(config-if)#ipv6 dhcp client pd snap-provided-prefix

We should pretty much get it straight away:

Router(config-if)#do show ipv6 dhcp interface
BVI1 is in server mode
 Using pool: default
 Preference value: 0
 Hint from client: ignored
 Rapid-Commit: disabled
Dialer0 is in client mode
 Prefix State is OPEN
 Renew will be sent in 10:44:15
 Address State is IDLE
 List of known servers:
 Reachable via address: FE80::200:F:FC00:0
 DUID: 
 Preference: 0
 Configuration parameters:
 IA PD: IA ID 0x000B0001, T1 43200, T2 69120
 Prefix: 2406:E001:XXXX::/48
 preferred lifetime 86400, valid lifetime 86400
 expires at Jul 02 2013 10:33 AM (81855 seconds)
 Information refresh time: 0
 Prefix name: snap-provided-prefix
 Prefix Rapid-Commit: disabled
 Address Rapid-Commit: disabled

If not, it may be necessary to up/down the Dialer0 interface.

So now we’ve got a prefix, but we can’t do anything with it yet. Let’s add some more stuff, in particular the default route for IPv6:

Router(config-if)#exit
Router(config)#ipv6 route ::/0 Dialer0

Now, let’s go into the configuration for the LAN side interface, and setup an address with that prefix we got from Snap:

Router(config)#interface BVI1
Router(config-if)#ipv6 enable
Router(config-if)#ipv6 address snap-provided-prefix ::1000:0:0:0:1/64

The last one is a bit of an odd command. The expression “::1000:0:0:0:1/64” sets the last 80 bits of the interface’s address, with the first 48 bits provided by the ISP. If you wanted to allocate another subnet in your network, you could change the “1000” to “1001” for example.

The subnet is /64 as always because this configuration will end up using EUI-64 for address assignment.

It should pretty much stick straight away:

Router(config)#do show ipv6 int br

...

BVI1                       [up/up]
    FE80::223:EBFF:FE2F:25D0
    2406:E001:XXXX:1000::1
Dialer0                    [up/up]
    FE80::223:EBFF:FE2F:25D0

...


Router(config)#

We’re almost online now, just one more thing: DNS.

I prefer to use stateless DHCPv6 for the configuration of IPv6 DNS servers (a fat lot of good for Android devices) but with RDNSS support almost non existent across mainstream platforms, we’ll have to live with it.

Here we’ll create a DHCPv6 pool just for handing out Snap’s two IPv6 DNS servers:

Router(config)#ipv6 dhcp pool default
Router(config-dhcpv6)#dns-server 2406:E000::100
Router(config-dhcpv6)#dns-server 2406:E000::200
Router(config-dhcpv6)#exit

And attach it to the BVI1 interface:

Router(config)#interface BVI1
Router(config-if)#ipv6 nd other-config-flag
Router(config-if)#ipv6 dhcp server default

Address configuration is done by ICMP in this configuration, so we’ve got to set the other-config-flag to let clients know to get the DNS servers via DHCP.

At this stage, anything connected to the network should now be online with IPv6. Windows 7+ clients do not need any additional configuration, the same should be true for most Linux distributions.

Running the “ipconfig /all” command on a Windows 7 machine confirms it’s all working nicely:

windowsipv6

Here we can see a full IPv6 address on this client which is:

Snap’s prefix (2406:e001) plus our customer prefix (censored) plus the prefix of the local subnet I configured earler (0x1000) and finally this machine’s EUI-64, all together, making a rather long string of digits.

Now the ultimate test: Ask Mr Google that question we’ve all asked at some point:

googleipv6

And there it is. Pretty impressive to be seeing that from New Zealand!

Hang on, we’re not done yet

I shouldn’t have to explain, that there’s no such thing as private IP addresses in IPv6. Everything is public.

So we should put some firewall rules in place to keep those script kiddies out of the home network. I’ve implemented this using reflexive ACLs

ipv6 access-list outbound
 permit tcp any any reflect tcptraffic-out-ipv6 timeout 30
 permit icmp any any reflect icmptraffic-out-ipv6 timeout 30
 permit udp any any reflect udptraffic-out-ipv6 timeout 30
!
ipv6 access-list inbound
 permit icmp any FE80::/64
 permit udp any FE80::/64 eq 546
 evaluate tcptraffic-out-ipv6
 evaluate udptraffic-out-ipv6
 evaluate icmptraffic-out-ipv6
!

I’ve left ICMP open on the Link Local interface, in case it’s needed by the ISP for any reason, also I’ve left UDP port 546 open because that’s what’s used by the prefix delegation process.

Now apply that to the Dialer0 interface:

Router(config)#interface Dialer0
Router(config-if)#ipv6 traffic-filter inbound in
Router(config-if)#ipv6 traffic-filter outbound out

The above gives us back more or less the level of security we took for granted with NAT IPv4 address sharing.

Getting it working on Android devices

Because Google still have their head up their arses when it comes to the matter of DHCPv6 support, and Cisco not having implemented RDNSS in IOS until v15.4 (the last version for Cisco 877 was 15.1) – the easiest option to make this work is to configure IPv4 DNS servers (configured by DHCPv4) which will give out AAAA records in DNS responses.

Many ISPs (Including Snap’s) don’t. So you’ll have to find some others.

Acquisition of an Agilent 16702B

It was only a matter of time before I was going to own one of these. Having used the 16700A on the job more than 10 years ago, it was one piece of kit I never forgot the enjoyment of using.

HP 16700/Agilent 16702B
Agilent 16702B in action

It also was inevitable that it’d be an 1670X that I’d go for, not for cost reasons, but to some extent. The affordable 16900’s are clapped out old Pentium III based units that won’t go to anything newer than the ancient Windows XP. This HP-UX based unit on the other hand, is timeless.

One of the first jobs: Replace that flaky, slow old SCSI hard disk with something a bit more modern. As no one has demonstrated any kind of practical (and cost effective) SSD solution for these units yet, I’m not keen to go splashing out on an expensive SCSI to SATA adapter which’ll be unlikely to work. The best hard disk option for repairers appears to be using SCA Ultra320 hard disks from old servers. They’re inexpensive, good performing, large and plentiful.

But first there is an annoying problem: Mine being one with the built in CD-ROM, the hard disk is mounted the opposite way to CD-ROM less units, and the offset of the connector with adapter on the incumbent disk arrangement makes it almost impossible to fit the SCA disk with adapter without slashing up the metalwork, or rebuilding the large SCSI ribbon cable, so I’ve had to make up this little “offsetter” cable to deal with it easily.

scaadapter

And here it is back in the LA

scaadapter_installed

During the re-install I found that the installer just couldn’t seem to cope with the 146GB drive I had installed. I don’t think it’s completely impossible but the LVM configurator is hard coded to always use the whole drive, then complain that it’s too large for the bootloader to boot from. In the end I copped out and installed it on another 9.1GB disk and DD’d it over to my new drive. The bootloader doesn’t mind massive drives, just so long as the root VG doesn’t span its entirety.

I’m not sure where the line between ‘works’ and ‘doesn’t work’ is in terms of disk size, but can confirm that a 73GB drive works, whereas 146GB doesn’t. Maybe 128GB is the maximum?

To transfer the smaller partition set onto the large drive was easy. I simply attached both drives to the analyser at once, boot into the recovery shell from the install CD-ROM and run these commands:

# loadfile dd
# dd if=/dev/dsk/c0t5d0 of=/dev/dsk/c0t6d0 bs=1048576

That took about 5 hours. Note here that SCSI ID 5 is the old 9.1 GB disk I just installed the OS on, and ID 6 is the newer 146GB drive. This had the disadvantage that I’ve wasted most of the drive, but it’s not like it’s ever going to be needed, and only using less than 10% of the drive has considerable performance advantages as the heads barely ever have to move a millimeter to boot the LA.

The upgrade was definitely worth it. With the old drive radiating enough heat to cook a steak, and producing the sound of a hundred maracas in a washing machine, this new drive is cool quiet and a lot faster. It’s now more responsive, and also boots about 15 seconds faster than before. It’s just a shame the rest of it makes a noise level somewhere between a hovercraft and a jet engine.

While I had the unit open – I took the opportunity to photograph two rather sought after but difficult to obtain items:

HP/Agilent 5063-9262 128MB
RARE: HP/Agilent 5063-9262 128MB memory upgrade

This is one tremendously exotic bit of RAM. It is similar to the memory found in old HP-UX workstations which had between one and four 64MB memory modules, but this particular one is a completely logic analyser specific pair of 64MB modules on a single 128MB PCB, despite the system reporting it as two 64MB upgrades.

HP/Agilent 5063-9262 128MB
5063-9262 Underside

Sadly these memory upgrades are only feasibly obtainable with a unit that was sold with them. Keysight apparently have some stock of the above upgrade, but with shipping and administrative charge, it’s cheaper to just buy a used Option 003 analyser, pinch its ram and throw it away.

HP/Agilent 16600-66518 Video memory upgrade
UNOBTAINABLE: HP/Agilent 16600-66518 Video memory upgrade

Even more difficult to come by is the video memory upgrade, which increases maximum resolution from 1280×1024 to 1600×1200. So far as I can tell this upgrade is effectively useless as it will only output 1600×1200 @ 75Hz which no LCD monitor will accept, as 60Hz is the maximum refresh rate for all LCD panels, unless the monitor happens to have some kind of intermediate buffering mechanism which I am unaware of any examples of.

Interestingly though there is a “user defined” display mode which I hoped would allow entry of a modeline or EDID but thus far I have not found any interface to configure it.

HP/Agilent 16600-66518 Video memory upgrade
16600-66518 Underside

The best way to use this Analyser appears to be the same way that I did on the job all those years ago: Remote X11

I was a little disappointed to find that after logging via Telnet using the “logic 192.168.0.x:0.0” format, that nothing happened? I don’t remember remote X11 being a difficult thing to use on these units. After trying all sorts of X servers, nothing worked at all!

In the end, I followed this guide, got a shell on it, reset the password for the secret “hplogicz” user.

(Quoted from http://www.perdrix.co.uk/)

As the system is booting, use the Esc key to interrupt the boot process, then issue the command BO PRI ISL.  When it asks you if you wish to interact with the boot process, respond with a “y” and press enter, then at the ISL> prompt, issue the command:

hpux -is

to get into single user mode.

Once you have a command prompt, you can use passwd root to change the root password.

In my case I wasn’t interested so much in resetting the root users password (but what the hey, why not) – but instead the hplogicz user which is already in place for this kind of use.

# passwd hplogicz

– and then reboot the LA, logged in via telnet with this account and started the logic analyser application manually with the following commands:

logic:/home/hplogic> export DISPLAY=192.168.0.31:0.0
logic:/home/hplogic> vp &
Agilent 16702B running with remote X11 on MobaXTerm
16702B running with remote X11 on MobaXTerm

So it appears that on mine, the program that normally is supposed to start the remote session (/usr/sprockets/bin/sessionWrapper) wasn’t working, but can be manually fudged around by starting vp the old fashioned way.

Auto power on after AC loss mechanism for PC mainboards

As many have said, when embarking on a project, it’s always the smallest details that kick your arse, and today, I’ve hit one of those.

A while back, still mourning the loss of the Intel Desktop Board line, I purchased a Jetway NF9E-Q77 as the Intel DQ77KB had become unobtainable, but this Jetway board, despite being sold as an industrial board, seems to be missing one of the most obvious features you’d expect from an industrial board: Auto power on. I’m rather baffled by this, further by the assertion of use for digital signage, if one of these ends up driving a large display high above the ground, does someone have to reach up to it with a long pole to press the power button every morning?

My first attempt at resolving this was to connect the +PWR_ON (power button) to the boards +5V supply (via a 4.7K resistor), this works good, because when the board is off, +5V is 0v, which is the same as pressing the power button, which just connects +PWR_ON to GND. As luck would have it, it powers on during the falling edge so it works a treat. Problem is – I couldn’t turn the darn thing off, because after shut down it goes right ahead and turns its self back on again, as you’d expect. Not exactly the behaviour I wanted.

Second bodge: This seems to be a common trick, attaching some kind of capacitor across the power switch. This works too. Most of the time…

Given that I want to be able to shut this machine down, and require that it always turns back on when AC power is connected, to heck with it, I’m going to have to use some kind of Microcontroller.

pic12c508a pic12c509a
ANCIENT HISTORY: A PIC12C508A purchased in error

A while back I bought this little relic from a high street electronics retailer (Maplin). I went in there to buy the modern (and common) 12F675, but came out with a 12C508. Was it that they were out of 12F675’s, or perhaps they gave me the wrong part? I don’t know for sure, but I doubt it. Most likely is that my mind was harping back to the bygone era of EPROM PICs, and I really did ask for it.

I find it interesting that high street retailer sells something like this, because this line of PICs is really quite difficult to work with, and is the last thing that the average walk-in-off-the-street hobbyist would ever want to tangle with:

  1. It requires specialist kit to download code onto it, i.e the £1000+ MPLAB PM3, or a high voltage benchtop EPROM programmer
  2. It’s OTP (One Time Programmable) so unless you’ve got a whole tube of them (who does right?) there’s only one chance to get the code right
  3. It uses Microchips’ most basic 12-bit instruction set, for which, C compilers don’t support, so it’s got to be programmed with the dreaded PIC12 ASM language

So what am I going to do here? Cop out and use a 12F675, or conquer one of these once again. Not having written any ASM for many years, I can already see what should be a 1 hour task turning into a 6 hour curiosity project.

In order to make absolutely certain that the machine is turned on in all cases, I decided to make it work like this:

  1. +5v Standby voltage powers up PIC
  2. PIC waits 3 seconds
  3. PIC tests if machine is on (by sampling +5V main supply)
  4. If powered on, go to step 7
  5. If not, PIC presses power button for 500ms
  6. Go to step 2
  7. Do nothing until powered off and on again

The device would only need 4 connections:

PC Power on device
The schematic
  1. The +5V standby voltage, which pin 9 on an ATX power supply cable, failing that, most mainboards will have it available on at least one connector, in my case I found it on the CIR header.
  2. The main +5V. This is found just about anywhere, and is used only to test if the PC is on.
  3. The power on button active signal. This is either pin 8 or 6 on the front panel header, One of those two is connected to ground, ignore that one and connect the other to this device. It’s no problem to leave the physical power button connected, this device will not interfere with its operation.
  4. Ground. Take your pick where to connect this.

If using an Intel Desktop Board, or one that is designed to be compatible, the Custom Solutions Header has all four of these connections.

PIC Based pc power on device
The device built on prototype board

And here’s the source code (download project). Understanding that few would be equipped and comfortable attempting this on an OTP PIC, It also works on PIC12F675 when use12f675 is set to 1.

use12f675 equ 0

if use12f675 == 1

#include "p12f675.inc"
processor 12f675
list f=inhx8m
__config (_INTRC_OSC_NOCLKOUT & _MCLRE_ON & _WDT_OFF & _CP_OFF & _CPD_OFF & _BODEN_OFF)

delay_ms_arg equ 0x20
delay_s_arg equ 0x21
add_arg equ 0x22

else

#include "p12c508a.inc"

processor 12c508a
list f=inhx8m
__config (_IntRC_OSC & _MCLRE_ON & _WDT_OFF & _CP_OFF)

delay_ms_arg equ 0x07
delay_s_arg equ 0x08
add_arg equ 0x09

endif

; Start of code

org 0x00 ; reset vector
goto main

delay_ms
movf delay_ms_arg, f
btfss STATUS, Z
goto outer_loop
retlw 0
outer_loop
movlw 0xF9
movf add_arg, w
inner_loop
movlw 0xFF
addwf add_arg, f
btfss STATUS, Z
goto inner_loop
nop
decfsz delay_ms_arg, F
goto outer_loop
retlw 0

delay_s
movlw 0xFA
movwf delay_ms_arg
call delay_ms
movlw 0xFA
movwf delay_ms_arg
call delay_ms
movlw 0xFA
movwf delay_ms_arg
call delay_ms
movlw 0xFA
movwf delay_ms_arg
call delay_ms
decfsz delay_s_arg, f
goto delay_s
retlw 0

main
movlw 0x00
movwf GPIO

movlw 0x3D
if use12f675 == 1

; 12F675
bsf STATUS, RP0 ; select register bank 1

movwf TRISIO

movlw 0x00 ; All A/D off
movwf ANSEL

bcf STATUS, RP0 ; select register bank 0

movlw 0x07 ; Comparators disconnected
movwf CMCON
else

; 12C508A
tris GPIO
endif

main_loop ; Power button pressing loop

movlw 0x03 ; 3 Seconds per pass
movwf delay_s_arg
call delay_s

btfsc GPIO, 0 ; System now on? Exit if so
goto infinite_loop

bsf GPIO, 1 ; Assert power button

movlw 0xFA ; 250ms delay
movwf delay_ms_arg
call delay_ms

movlw 0xFA ; 250ms delay
movwf delay_ms_arg
call delay_ms

bcf GPIO, 1 ; De assert power button

goto main_loop

infinite_loop ; Done till next power on
goto infinite_loop

end