How to sense Thermostat events with Arduino?

I would like to interface my thermostat to an Arduino to receive various thermostat events (heat, 2nd stage heat, cool, fan). I understand the thermostat is 24V AC so where I'm stuck is how can I safely interface this with the Arduino (e.g. heat on reads 5 volts). I've done quite a bit of searching but what I find is people are controlling their thermostat. I only want to "listen" to the thermostat events. My plan is to run a separate cable to the thermostat since I don't want to in any way alter or disturb the furnace wiring. I've looked at my thermostat and I have the following contacts: Power Rh, Rc (heat and cool are jumpered), Common (C) , Heat (W), 2nd Stage Heat (W2), Cool (Y), and Fan (G)

Ok, for anyone else interested in this problem, I, found a circuit on ray's hobby that seems like it will work (#option 4) 24VAC to 5VDC Conversion « RAYSHOBBY.NET

Just an observation: waaaaaay too much insulation stripped off those wires. The yellow and white are asking for a short...

Is the optocoupler as simple as connecting a thermostat line with a resistor to the AC side. Then do the same on DC side with 5V and current will flow when AC side is on? If so this seems like the ideal solution for me.

@jimboZA Yeah good point about the exposed wire

If I was doing this, my first choice would be to use a current-limiting resistor and an AC input optocoupler like the ones found on this page:

My second choice would be to use a bridge rectifier to convert the AC to DC, a filter capacitor to filter out the ripple and then a current-limiting resistor feeding a DC input optocoupler. Similar to a power supply circuit.

Third, would be a bridge rectifier with filter capacitor and a voltage divider to drop the 24V DC down to 5V or less.

Sorry, I'd provide a schematic of each example but I currently have enough trouble typing (recent hand injury) and can't draw anything at the moment.

While you probably already know which wires perform each function (just for future reference of others attempting this), let me add that AC voltage will be seen:

Across W and C when the thermostat is calling for heat,
Across W2 and C when calling for auxiliary heat,
Across Y and C when the thermostat is calling for cooling,
And across G and C when the fan switch on the thermostat is set for manual or 'Fan On.'

Monitoring the actual running of the fan cannot be done from the thermostat, as it is also controlled directly from the furnace itself, most likely by directly switching the mains voltage rather than 24V DC.

And Jimbo is right, WAY too much exposed conductor. You should fix that ASAP.

Some more digging has revealed a similar post. Seems this guy used the circuit I posted but it's unclear since a schematic is not referenced 24 volts AC to arduino input - Interfacing - Arduino Forum

Found a optocoupler solution ASK AN EDUCATOR – “How can I measure AC voltage with my Arduino?” « Adafruit Industries – Makers, hackers, artists, designers and engineers!

Right now I'm leaning towards getting 4 of these

I would use the optocoupler method for isolation. But then on the arduino side you will need some kind of circuit to rectify the signal for the arduino to read. Probably just a diode and capacitor will do.

If you use the half-wave rectifier circuit from Ray's Hobby you can drop C2 way down since you are not going to need anywhere near 300mA.
I'm not sure how well it will work though since you may not see anywhere near 24v depending on the load the contactor draws.
I think the easier way would be to take apart the thermostat and solder sensor wires onto the relays to tell when they are open/closed. The voltages will likely be DC 3V or 5V - easy to sense on the arduino.

Yet another option would be inductive sensing. You'd probably need an op amp for each channel as I doubt the ADC gain available on the arduino would be sufficient.
This circuit would give you a starting point.

A friend of mine (EE) created this circuit.

I think I'll go with this one since it's the simplest and I'm not sure exactly about how to wire up the optocoupler. I'll send him any feedback I get here

This neatly drawn and carefully calculated schematic could have a problem: it assumes that the 24V AC sense supply will be exactly 24V when in practice that is only a nominal value that may not be exact and may vary. And, in the real world there is likely to be electrical noise on the signal and sometimes voltage transients or spikes that could be much greater than 24V. Those voltage variations and spikes will be passed on directly to the Vout 5V output, albeit at a reduced level.

The maximum voltage that can be safely applied to an Arduino input pin doesn't seem to be specified at a quick look, but unless the inputs are known to be protected on the board, it should be assumed that the input voltage shouldn't exceed around 5.5V or the board could be damaged.

The above design could be modified to eliminate the risk but it would mean adding two more components, a zener diode and a resistor, to clamp the Vout voltage at a level at or below 5V whatever the input. The R1, R2 potential divider would have to be redesigned to raise the voltage to 7V or more, exact value not critical and could be 12V, and then a resistor from that point would supply a back biased 4.7V or similar zener diode to provide a safe Vout voltage.

One of the opto coupler options above would probably be a simpler and safer solution.


I shouldn't really have said that voltage transients and spikes will be passed on directly to Vout because the quite large capacitor C1 will have a smoothing effect, but a zener diode or other means of clamping Vout at 5V or slightly below is needed to prevent the risk of damage to the Arduino board unless its inputs are known to be protected.