How could I go about programming a switch (based on solid-state relay or a triac) that triggers on zero-crossing power?
For these not familiar with the subject: Switch 230V power on, when the sine wave of the power line crosses zero - the result is minimizing the electromagnetic disturbances resulting from rapid spike in current.
Specifically, I'd prefer to move as much into software as possible. The detection circuit consisting of a small transformer, a diode and a couple resistors to keep levels and currents in check provides "1" when the AC input power is in positive half, "0" in negative, attached to an input GPIO pin. The output consists of a few solid state relays and bare essentials to keep them running (pull-ups etc), attached to output GPIO pins.
The problem is timing: with 50Hz AC we get 100 zero-crossings in a second, one half-cycle is 10ms. To get within reasonable distance from zero-crossing to keep said EMI low we shouldn't activate the output more than 10% past (or before) the event of zero-crossing, that means +-1ms tolerance. That doesn't mean 1ms reaction time - we can reasonably expect the next zero-crossing to occur precisely 10ms after the first one, or the fourth - 40ms. It's about granularity - if we allow 20ms for reaction, it must be between 19 and 21ms, not 18 or 22.
How can I implement such a timer - trigger output GPIO either within 1ms since input detects an edge, or within a fixed multiple of 10ms since then - preferably with allowance for some negative bias (say, the transformer and the relay introduce 1.6ms delay; so I want the trigger to go off 8.4+(n*10)ms since the input pulse, that way the bias counteracts the delay introduced by the circuit.) - all of course "on user demand", say, user writes "1" to a /sys/class/... file and on nearest (roughly) opportunity the output goes "on". User writes "0", and when the zero-crossing arrives, specific relay disengages.
I believe this would require writing or hacking a kernel module. Could you point me to what handles the GPIO pins of Raspberry Pi in the kernel, and what kind of timers could I attach to it (unless there are some in place already) to get this kind of functionality?