Projects

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.

Solar Cluster: Selecting batteries and sources

I’ve been doing quite a bit of thinking on this. Solid-state works but suffers from voltage drop. Relays work but either require the coil to be energised constantly (~1W load) unless you look for latching relays, for which 30A units are hard to come by.

These look promising though. A latching relay is nice since I only need to pulse the coil, not hold it on indefinitely.

That got me thinking what else can I use to switch power? The ideal for me is something that has practically no voltage drop and remembers its state without power. A latching relay fits this requirement. So does a uniselector or stepping switch. Those were commonplace in telephone exchanges years ago, but have since gone the way of the dodo as semiconductor technology replaced it.

The nice thing about a uniselector though for my application is you can switch between N points, instead of just two like a regular relay. So if I buy a third battery, I can wire it up to the uniselector, and have it switch the compute load between the batteries. Likewise, I can connect a charger to the battery most in need of a charge. MCU measures battery voltages, picks the battery with highest voltage to run the load, and the lowest voltage to get a charge. Easy.

That got me thinking… can I make a uniselector? Well of course I can! I basically need to make a rotary switch that can revolve around indefinitely. The shaft of the switch would then be turned by a DC motor.

The stator of a N-way switch would have N+1 pads, one which is the “common”, and the other N would be to each selection. The common pad would be a 180° arc, the others would be 180°/N.

The rotor would feature two brushes 180° apart with a wire connecting them. It is free to move vertically, but must rotate with the shaft, a spring between a nut on the end of the shaft and the rotor applies tension to keep the rotor pressed firmly against the stator.

The interface between rotor and stator features some triangular grooves, so that when the rotor is turned, it pushes it away from the stator, breaking contact. When the rotor passes a critical point, the spring pressing the rotor against these grooves makes the rotor “want” to continue turning until it hits the bottom of the groove, at which point it “sinks” down towards the stator and eventually makes contact again.

Visually, it looks like this:

A small microswitch mounted on the stator could tell us when touch-down takes place, if we use the normally-closed contact to power the motor it will automatically stop the motor when the next position is reached. We then just need to override that open switch by applying a pulse to get things moving.

Power is only needed when we want to change the selector switch. This should be simple enough to fabricate here out of plywood. I don’t have a 3D printer, but you could do it with one of those very easily.

The nature of this switch makes it a break-before-make switch, which has a downside when using it to select which battery to use: there’s a momentary break in power.

I can use diodes to carry the current temporarily. If I run a high-current diode from each battery to the output via a current sensor. If the current sensor measures current flowing through the diodes whilst a battery is selected, then we know that battery is lower than the others by at least the diode voltage drop, and we should consider switching.