Solar Cluster: Power distribution harnesses

So, having got the rack mostly together, it is time to figure out how to connect everything.

I was originally going to have just one battery and upgrade later… but when it was discovered that the battery chosen was rather sick, the decision was made that I’d purchase two new batteries. So rather than deferring the management of multiple batteries, I’d have to deal with it up-front.

Rule #1 with paralleling batteries: don’t do it unless you have to. In a perfect world, you can do it just fine, but reality doesn’t work that way. There’s always going to be an imbalance that upsets things. My saving grace is that my installation is fixed, not mobile.

I did look at alternatives, including diodes (too much forward voltage drop), MOSFET switching (complexity), relay switching (complexity again, plus contact wear), and DIY uniselectors. Since I’m on a tight deadline, I decided, stuff it, I’ll parallel them.

That brings me to rule #2 about paralleling batteries: keep everything as close to matched as possible. Both batteries were bought in the same order, and hopefully are from the same batch. Thus, characteristics should be very close. The key thing here, I want to keep cable lengths between the batteries, load and charger, all equal so that the resistances all balance out. That, and using short runs of thick cables to minimise resistance.

I came up with the following connection scheme:

You’ll have to forgive the poor image quality here. On reflection, photographing a whiteboard has always been challenging.

Both batteries are set up in an identical fashion: 40A fuse on the positive side, cable from the negative side, going to an Andersen SB50/10. (Or I might put the fuse on the negative side … haven’t decided fully yet, it’ll depend on how much of each colour wire I have.) The batteries themselves are Giant Power 105Ah 12V AGM batteries. These are about as heavy as I can safely manage, weighing about 30kg each.

The central harness is what I built this afternoon, as I don’t yet have the fuse holders for the two battery harnesses.

The idea being that the resistance between the charger and each battery should be about the same. Likewise, the resistance between the load and each battery should be about the same

The load uses a distribution box and a bus bar. You’ve seen it before, but here’s how it’s wired up… pretty standard:

You might be able to make out the host names there too (periodic table naming scheme, why, because they’re Intel Atoms) … the 5 nodes are on the left and the two switches to the right of the distribution box. I have 3 spare positions.

In heavy black is the 0V bus bar.

This is what I’ve been spending much of my pondering, doing. Part of this harness is already done as it was installed that way in the car, the bit that’s missing is the circuit to the left of the relay that actually drives it. Redarc intended that the ignition key switch would drive the relay, I’ll be exploiting this feature.

Some time this week, I hope to make up the wiring harnesses for the two batteries, and get some charge into them as they’ve sat around for the past two months in their boxes steadily discharging, so I’d be better to get a charger onto them sooner rather than later.

The switch-over circuit can wait for now: just hard-wire it to the mains DC feed for now since there’s no solar yet. The principle of operation is that the comparator (an LM311) compares the solar voltage to a reference (derived from a 5V regulator) and kicks in when the voltage is high enough. (How high? No idea, maybe ~18V?). When that happens, it outputs a logic high signal that turns off the MOSFET. When too low, it pulls the MOSFET gate low, turning it on.

The MOSFET (a P-channel) provides the “ignition key switch” signal to the BCDC1225, fooling it into thinking it is connected to vehicle power, and the charger will boost as needed. The key being that the BCDC1225 makes the decision as to whether the battery needs charging, and how much charge.

By bolting together off-the-shelf parts, we should have something that I can source replacements for should the smoke escape, and there’s no high voltages to deal with.

Solar Cluster: Rack taking shape

Well, it’s been a while since I last updated this project. Lots have been due to general lethargy, real life and other pressures.

This equipment is being built amongst other things to host my websites, mail server, and as a learning tool for managing clustered computing resources. As such, yes, I’ll be putting it down as a work expense… and it was pointed out to me that it needed to be in operation before I could start claiming it on tax. So, with 30th June looming up soon, it was time I pulled my finger out and got it going.

At least running on mains. As for the solar bit, well we will be doing that too, my father recently sent me this email (line breaks for readability):

Subject: Why you're about to pay through the nose for power - ABC News
 (Australian Broadcasting Corporation)
To: Stuart Longland
From: David Longland
http://www.abc.net.au/news/2017-06-19/…
   …why-youre-about-to-pay-through-the-nose-for-power/8629090

Hi Stuart,

This is why I am keen to see your cluster up and running.  Our power 
bill is about $300 every 3 months, a lift in price by 20% represents 
$240pa hike.

Dad

Umm, yeah… good point. Our current little server represents a small portion of our base-load power… refrigeration being the other major component.

I ordered the rack and batteries a few months back, and both have been sitting here, still in the boxes they were shipped in, waiting for me to get to and put them together. My father got fed up of waiting and attacked the rack, putting it together one evening… and last night, we worked together on putting a back on the rack using 12mm plywood.

We also fitted the two switches, mounting the smaller one to the lid of the main switch using multiple layers of double-sided tape.

I wasn’t sure at first where the DIN rail would mount. I had intended to screw it to a piece of 2×4″ or similar, and screw that to the back plane. We couldn’t screw the DIN rail directly to the back plane because the nodes need to be introduced to the DIN rail at an angle, then brought level to attach them.

Considering the above, we initially thought we’d bolt it to the inner run of holes, but two problems presented themselves:

  1. The side panels actually covered over those holes: this was solved with a metal nibbling tool, cutting a slot where the hole is positioned.
  2. The DIN rail, when just mounted at each end, lacked the stability.

I measured the gap between the back panel and the DIN rail location: 45mm. We didn’t have anything that was that width which we could use as a mounting. We considered fashioning a bracket out of some metal strip, but bending it right could be a challenge without the right tools. (and my metalwork skills were never great.)

45mm + 3mm is 48mm… or 4× plywood pieces. We had plenty of off-cut from the back panel.

Using 4 pieces of the plywood glued together and clamped overnight, I made a mounting to which I could mount the DIN rail for the nodes to sit on. This afternoon, I drilled the pilot holes and fitted the screws for mounting that block, and screwed the DIN rail to it.

At the far ends, I made spacers from 3mm aluminium metal strap. The result is not perfect, but is much better than what we had before.

I’ve wired up the network cables… checking the lengths of those in case I needed to get longer cables. (They just fit… phew! $20 saved.) and there is room down the bottom for the batteries to sit. I’ll make a small 10cm cable to link the management network up to the appropriate port on the main switch, then I just need to run cables to the upstairs and downstairs switches. (In fact, there’s one into the area already.)

On the power front… my earlier experiments had ascertained the suitability of the Xantrex charger that we had spare. The charger is a smart charger, and so does various equalisation and balancing cycles, thus gets mightily confused if you suddenly disconnect the battery from it by way of a MOSFET. A different solution presented itself though.

My father has a solar set-up in the back of his car… there’s a 12V 120W panel on the roof, and that provides power to a battery system which powers an amateur radio station and serves as an auxiliary battery. There’s a diode arrangement that allows charging from the vehicle battery system.

In an effort to try and upgrade it, he bought a Redarc BCDC1225 in-vehicle MPPT charger. This charger can accept power from either the 12V mains supply in a vehicle, or from a “12V” solar panel. The key here, is it relies on a changeover relay to switch between the two, and this is where it wasn’t quite suitable for my father’s needs: it assumed that if the vehicle ignition was on, you wanted to charge from the vehicle, not from solar.

He wanted it to switch to whichever source was more plentiful, and had thought the unit would drive the relay itself. Having read the manual, we now know the signal they tell you to connect to the relay coil is there to tell the charger which source it is plugged into, not for it to drive the relay.

The plan is therefore:

  • use a 240V→12V AC-DC switch-mode power supply to provide the “vehicle mains” DC input to the charger.
  • measure the voltage seen at the solar input with a comparator and switch over when it is above some pre-defined voltage (use hysteresis to ensure it doesn’t oscillate)
  • use the output to drive a P-channel MOSFET attached to the “vehicle mains”, which drives the relay.

Toy Synthesizer: 74HC573, no substitute for the ‘574

So… when laying out this board, I decided I’d swap the 74HC374 for the much nicer ‘574 for managing the MOSFETs. No problem, well, one minor snag, neither Jaycar nor Altronics carry the ‘574.

They carry the ‘374… Jaycar is where I got mine originally. They also carry the very similar ‘573. I had intended to order some ‘574s for when the boards arrived, but they sort of turned up unexpectedly… so didn’t get a chance.

The fundamental difference? Apart from the ‘574 being edge triggered, the ‘573 also is active high on the logic enable pin. I had wrongly assumed it was active low .

Naturally, I did try to hack around this fundamental difference:

Tried to get that leg in focus, but it’s difficult when the LCD of the camera is such low resolution (and the viewfinder is an even lower resolution LCD). Basically, I nibbled the leg of the IC with my sidecutters and bent it up. To the pad, I solder the gate of a 2N7000 MOSFET, bend the drain pin up to meet the now floating-in-air LE pin, and run a resistor (a 3k3) to Vcc.

That works somewhat… it might be possible to introduce some more state machine cycles to handle the kludge… although the real fix is to use the correct part in the first place.

Toy Synthesizer: First board built

So, I haven’t yet tried out the MOSFET outputs, but nearly all the GPIO inputs work. I say nearly… there is one that doesn’t on channel 4.

I can test by shorting out the 0V and GPIO pins with a multimeter probe. Not sure why one channel isn’t working yet, that I’ll have to debug tomorrow.

It is worth noting that the MC14066s here are older than I am if I am reading the date codes correctly. Still, they’ve been kept in a tube all these years, so no reason why they’d suddenly pop. More probable, I’ve goofed somewhere in the wiring of this.

At worst, I should be able to de-solder the faulty chip (if that is the case) and put another one in its place… I have plenty lying around. The fact that its mate on the other side is working fine, is promising.

The up side is this board doesn’t look like a big mess of wires like the last prototype. Once I get the faulty channel sorted, I should be able to make the I/O modules that will provide the MOSFET outputs, ESD protection and switch debouncing.

One thing I’ll probably do in future: use bigger vias for my jumper wires, and actually mark on the silk screen component values and the jumper wire routes.


Did some probing… turns out my jumper wire wasn’t making good contact with the via … a dry joint. Definitely I’ll make the vias bigger next time!

Toy Synthesizer: Boards have arrived

So, I had a surprise delivery this morning… 10 PCBs for the new synthesizer.

These are just two-layer affairs… with the idea being that anyone can manufacture these themselves. The top layer if made at home is done just by covering one side of a double-sided PCB with tape. The other can be done by hand with a dalo pen, using photographic methods or using toner transfer.

One thing I did have originally, and lost when I told Kicad to delete all footprints when re-working the design, is the mounting holes in the corners, something I’ll have to re-add.

I’ll have to pick up some 74HC574s (or perhaps ‘573s, since that’s what the hobby shops sell… won’t matter for this project, either will do) and get soldering this weekend.

Toy Synthesizer: First working prototype

So… after some cursing at me being dimwitted enough to get the amplifier around the wrong way… and luckily the amplifier is a tough little beast… I managed to get some basic functions going.

It is supposed to be polyphonic, the synthesizer supports it, and it does actually work, but it seems my GPIO arrangement isn’t picking up multiple buttons correctly.

Ahh well, we’ll get there. 🙂 At least it is making noises and flashing lights on cue, so in that sense, a minimum viable product has been achieved.

Ohh, and I was able to bump the sample rate to 16kHz. 32kHz was a bit much for the little MCU though, it couldn’t quite keep up.

Code size at this point is 3.6kB… so still lots of room left. The answer might be to implement an I²C slave mode so I can interrogate it from the host.

Toy Synthesizer: Getting OC1B & OC1D to play together

So… a bit of head scratching this afternoon. I had working PWM on the LEDs… which was fantastic.

With the trade-off of LEDs being ⅛ brightness maximum, which is fine since the LED strings that I’ve been given for this project would make Manfred Mann proud…

I was a little stumped with my audio PWM. I could not get a peep out of it, not via the amplifier or anything else. Tracing back, I was getting nothing out of the PWM pin. Real strange. Looked up the data sheets, couldn’t see what I was doing wrong.

My code for initialising Timer1 looked like this:

	/* Timer 1 configuration for PWM */
	OCR1B = 128;			/* Initial PWM value: audio */
	OCR1D = 32;			/* Initial PWM value: light */
	OCR1C = 255;			/* Maximum PWM value */
	TCCR1A = (2 << COM1B0)		/* Clear OC1B on match,
					   nOC1B not used */
		| (1 << PWM1B);		/* Enable PWM channel B */
	TCCR1B = (1 << CS10);		/* No prescaling, max speed */
	TCCR1C = (3 << COM1D0)		/* Set OC1D on match,
					   nOC1D not used */
		| (1 << PWM1D);		/* Enable PWM channel D */
	TCCR1D = (0 << WGM10); /* Fast PWM mode */

It looked fine… even checked the header files to see there wasn’t some cock up in the headers. Never had an issue with avr-libc, but you never know, and of course, no problem there.

In exasperation, I swapped setting up TCCR1A and TCCR1C. Bingo, I had PWM both channels. Why? Turns out there are some bits in TCCR1C that shadow TCCR1A, and I was inadvertently setting those back to 0 when I set up TCCR1C. So my code now:

	/* Timer 1 configuration for PWM */
	OCR1C = 255;			/* Maximum PWM value */
	TC1H = 0;			/* Reset counter high bits */
	TCNT1 = 0;			/* Reset counter low bits */
	OCR1A = 0;			/* Initial PWM value: spare */
	OCR1B = 127;			/* Initial PWM value: audio */
	OCR1D = 127;			/* Initial PWM value: light */
	TCCR1A = (1 << PWM1B);		/*
					 * Clear TCCR1A except for PWM1B,
					 * we'll configure OC1B
					 * via the shadow bits in TCCR1C
					 */
	TCCR1B = (1 << CS10);		/* No prescaling, max speed */
	TCCR1C = (2 << COM1B0S)		/* Clear OC1B on match,
					   nOC1B not used */
		| (3 << COM1D0)		/* Set OC1D on match,
					   nOC1D not used */
		| (1 << PWM1D);		/* Enable PWM channel D */
	TCCR1D = (0 << WGM10);		/* Fast PWM mode */
	TCCR1E = 0;			/* Not used: PWM6 mode */

We still need to turn PWM1B on via TCCR1A… but we set the output control mode via TCCR1C to avoid clobbering our settings.

Having fixed that, I now have a second problem, in my dead-bugging of the amp, I got my left and right arse-about, which would explain why my amp is making no noise. That’ll be a tomorrow job methinks, at 22:30 UTC+10:00 it is too dark to work on PCBs. I’ll just keep myself amused looking at the waveform on the oscilloscope.

Toy Synthesizer: Peripheral detection and I²C bus enumeration

So these are some completely untested notes on how I might achieve auto-detection of peripherals and I²C devices.

The idea here is that a peripheral can be plugged into any of the 8 ports on the device. It won’t matter, because there’ll be a standard boot-up procedure, consisting of:

  1. Deriving an I²C bus address (possibly by sampling ADC LSB bits to generate a random address) and verifying that there are no clashes by attempting to poll the derived address a few times.
  2. Performing a read of the bus roll-call I²C address to enumerate the IDs of all automatically-addressed I²C devices on the bus. During this step, the GPIOs are monitored: the slave should pulse the GPIO it is connected to as it “calls out” its ID.
  3. Measuring ADC readings at the GPIO pins and observing power-up state (common GPIO pin in high-impedance state)
  4. Pulling the common GPIO pin (MISO) high and seeing which GPIO pins go high.
  5. Pulling the common GPIO pin (MISO) low and seeing which GPIO pins go low.

The peripherals may be connected via a number of ways:

The boot-up procedure is used to determine what is attached, by performing some simple actions and observing the GPIO pin, which thanks to the ‘4066s, also doubles as an ADC.

As for I²C addressing… I do not want to have to program a unique address into each device. The concept here is instead that each device generates its own address, waits for a clear moment on the bus, then tries polling its proposed address to see if it gets an ACK. In the case of a time-out, it waits a random length of time and tries again when the bus is clear, and after a few times, can safely assume it has the address.

This gives rise to a problem though, knowing what the addresses of the neighbours are.

The idea here is to use a roll-call address. This is common to all units implementing the auto-addressing protocol. When a device hears the roll-call address, it tries to send its ID in reply. When another device with a numerically lower ID sends at the same time, the device sees the collision and tries again on the next byte. As each calls out its ID, it pulses the interrupt pin low (if it uses one).

The result from the master’s perspective is it sees a stream of IDs sorted from numerically lowest to highest, terminated by a stream of 0xff bytes. Direct peers are able to then detect who their peers are.

Timing of all of this will be the challenge. We want to ensure everyone has a unique ID by he time the first roll-call is performed so we can move on to detecting the dumb devices (LEDs and buttons). This network feature will be a stretch-goal of the project though, so plenty of time to think about that.

Toy Synthesizer: PWM Outputs work

So, I’ve done some tweaks to the prototype… namely fixing some wire assignments. I also had to drop my 1kΩ resistor on the input to a 100Ω as the voltage drop of the 1k was too high.

At the moment, I am seeing ~3V at the MCU, which is good enough.

Beneath the afro of wires, is the prototype.

… and this is the PWM LED control in action (animated GIF). So PWMing the output enable of a 74LS374 works, and doing the same on a 74HC574 should too.

So, I’ve done some tweaks to the prototype… namely fixing some wire assignments. I also had to drop my 1kΩ resistor on the input to a 100Ω as the voltage drop of the 1k was too high.

At the moment, I am seeing ~3V at the MCU, which is good enough.

Beneath the afro of wires, is the prototype.