SOLVED: Interfacing a smart thermostats pins with Arduino.

Prelude here: I know there is either an issue with how I am using the code or how I have this wired... hoping to understand where I am screwing up.

I have wired the terminals of a powerley smart thermostat to my arduino uno with the intention of reading the signals being sent from the thermostat. It works with Z-Wave which I have a SmartThings hub but I dont want to actually hook this into my system as I want to use in the basement and just capture the signals it sends so I could turn them into requests for my Nest. Right now it can only be linked to a hub from our power company and in order to override that and use raw Z-Wave it has to be wired in...whatever. If I can do it the arduino route its simpler.

My issue is either in how I set up my code or my understanding of the thermostat wiring. I have batteries in so nothing connected to the C terminal which usually supplies power to the thermostat. I am trying to read the states of the RC, Compressor, Heat and Fan terminals but when monitoring my Serial feed all 4 are always high which cant be the case. Here is the code:

// this constant won't change:
const int hvacpin = 2;    
const int comppin = 3;
const int fanpin = 4;
const int rcpin = 5;

// Variables will change:
int hvacState = 0;
int compState = 0;
int fanState = 0;
int rcState = 0;
int lastHvacState = 0;
int lastCompState = 0;
int lastFanState = 0;
int lastRcState = 0;

void setup() {
  // initialize the button pin as a input:
  pinMode(hvacpin, INPUT_PULLUP);
  pinMode(comppin, INPUT_PULLUP);
  pinMode(fanpin, INPUT_PULLUP);
  pinMode(rcpin, INPUT_PULLUP);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  hvacState = digitalRead(hvacpin);
  compState = digitalRead(comppin);
  fanState = digitalRead(fanpin);
  rcState = digitalRead(rcpin);

  if (hvacState != lastHvacState) {
    if (hvacState == HIGH) {
      Serial.println("A/C on");
    } else {
      Serial.println("A/C off");
    }
    delay(50);
  
  lastHvacState = hvacState;
  }
  
  if (compState != lastCompState) {
    if (compState == HIGH) {
      Serial.println("Compressor on");
    } else {
      Serial.println("Compressor off");
    }
    delay(50);

  lastCompState = compState;
  }
  
  if (fanState != lastFanState) {
    if (fanState == HIGH) {
      Serial.println("Fan on");
    } else {
      Serial.println("Fan off");
    }
    delay(50);
  
  lastFanState = fanState;
  }
  
  if (rcState != lastRcState) {
    // if the state has changed, increment the counter
    if (rcState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      Serial.println("RC on");
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("RC off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  
  // save the current state as the last state, for next time through the loop
  lastRcState = rcState;
  }


}

I suspect that I might be using the INPUT_PULLUP method wrong but I am not sure. Hopefully someone can point out my flaw.

Thanks!

Have you checked, with a DMM, if the inputs are actually changing?

If that's a conventional thermostat, the voltage on those pins would be 24Vac, which you wouldn't want on an Arduino pin. Is it?

wildbill:
If that’s a conventional thermostat, the voltage on those pins would be 24Vac, which you wouldn’t want on an Arduino pin. Is it?

It is indeed a conventional thermostat which, maybe I am misunderstanding how it works but it was my understanding that the 24Vac would only be being delivered to the C pin. It runs on 4 AA batteries without the C pin connected but I am having a difficult time measuring any DC voltage with it on as right now it turns off after a couple seconds before I can trip it to flip a pin. When the arduino is plugged in I can keep it on longer but there must be some sort of check looking for…SOMETHING that I am not aware of yet in order to keep it on. HVAC system wouldnt be sending anything back to the thermostat since thermostat basically only acts as an on/off switch.

IIRC, all the thermostat does is connect the voltage on R (red wire) when required to other terminals such as W through relays.

I assume now that your thermostat isn't actually attached to a any wires from the HVAC controller and you're just trying to persuade it to tell you which systems it would turn on if it were.

I don't know if the thermostat circuitry cares whether the incoming power wire is carrying 14Vac or 5VDC, but it might be possible to wire a ground & power connection from the Arduino and then wire the outputs with a pulldown.

For what sounds like an expensive fancy thermostat, I'd suggest that you get some definitive answers before you experiment though.

wildbill: IIRC, all the thermostat does is connect the voltage on R (red wire) when required to other terminals such as W through relays.

I assume now that your thermostat isn't actually attached to a any wires from the HVAC controller and you're just trying to persuade it to tell you which systems it would turn on if it were.

I don't know if the thermostat circuitry cares whether the incoming power wire is carrying 14Vac or 5VDC, but it might be possible to wire a ground & power connection from the Arduino and then wire the outputs with a pulldown.

For what sounds like an expensive fancy thermostat, I'd suggest that you get some definitive answers before you experiment though.

So here is the best part... it is a $100 thermostat but the power company was offering them for free. I ordered one because i wanted to just convert it to standard Z-wave but when i dug into that and realized that it required being installed and the hub to do (which is also free, ordered one of those too) i went back to the site and the thermostat was still listed as free and they let me order another one. Plan on using that for our second floor. They cut me off when I tried to order a third though. So at the end of the day im not out anything by using these outside their intended purpse and worst comes to worst ill use it as a nice temperature/sensor display to go alongside my other who house sensor network.

Ill try your suggestion as I think you may be on to something. It would make sense that the way the system generally works is as you described. The instructions indicate that if you are using batteries you cant use the C wire so im not entirely sure how it would work given that limitation but we will see.

wildbill: I don't know if the thermostat circuitry cares whether the incoming power wire is carrying 14Vac or 5VDC, but it might be possible to wire a ground & power connection from the Arduino and then wire the outputs with a pulldown.

Wiring in 10k pulldowns does at least alleviate the pins going directly to high which is good but using the 5v from the arduino to the C terminal on the thermostat without batteries didnt provide enough current to turn on the thermostat. Put the batteries back in and unplugged the c wire and still no go.

I'd be curious to see what the thermostat does with 5V from the Arduino on R, batteries installed and persuade it to call for heat. Do you get 5V from W?

wildbill: I'd be curious to see what the thermostat does with 5V from the Arduino on R, batteries installed and persuade it to call for heat. Do you get 5V from W?

Wired up this way and W shows no difference between switching between heat and AC. It goes a bit wild on the multimeter.

Do you mean switching between heat and cooling modes?

You're going to need the thermostat in heating setting and with the set point higher than whatever it senses in the room. When that happens with my home setup, I hear a relay click. YMMV.

wildbill: Do you mean switching between heat and cooling modes?

You're going to need the thermostat in heating setting and with the set point higher than whatever it senses in the room. When that happens with my home setup, I hear a relay click. YMMV.

Sorry should have been more descriptive. I received the hub since i started this thread earlier today and I was able to sync the thermostat to it so I can switch modes from my phone which is more convenient for testing purposes. I am able to hear the click of the relay when it sends the signal to change but im still getting no signal to the arduino when that happens.

See if a multimeter can shed some light. Look for connectivity between the thermostat terminals and see how it changes when the relay clicks.

wildbill: See if a multimeter can shed some light. Look for connectivity between the thermostat terminals and see how it changes when the relay clicks.

Ended up figuring it out... Found an excellent write up regarding how thermostat circuits are wired and the power for the relays comes in from the AC/Heater on the RC and RH terminals and then flips the relays from there.

I appreciate all of your help! I would not have been able to solve this without being able to bounce ideas back and forth with someone!

And does it work with the Arduino?

Yes! And very intuitively at that. Here is the code that ended up working. 5V from the Arduino into the bridged RC/RH pin and 10k resistors to ground on the digital pins:

 // this constant won't change:
const int heatpin = 2;    
const int acpin = 3;
const int fanpin = 4;

// Variables will change:
int heatState = 0;
int acState = 0;
int fanState = 0;
int lastheatState = 0;
int lastacState = 0;
int lastFanState = 0;

void setup() {
  // initialize the button pin as a input:
  pinMode(heatpin, INPUT_PULLUP);
  pinMode(acpin, INPUT_PULLUP);
  pinMode(fanpin, INPUT_PULLUP);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  heatState = digitalRead(heatpin);
  acState = digitalRead(acpin);
  fanState = digitalRead(fanpin);

  if (heatState != lastheatState) {
    if (heatState == HIGH) {
      Serial.println("Heat on");
    } else {
      Serial.println("Heat off");
    }
    delay(50);
  
  lastheatState = heatState;
  }
  
  if (acState != lastacState) {
    if (acState == HIGH) {
      Serial.println("AC on");
    } else {
      Serial.println("AC off");
    }
    delay(50);

  lastacState = acState;
  }
  
  if (fanState != lastFanState) {
    if (fanState == HIGH) {
      Serial.println("Fan on");
    } else {
      Serial.println("Fan off");
    }
    delay(50);
  
  lastFanState = fanState;
  }


}

My next trick will be to incorporate MQTT calls to my Home Assistant server in order to trigger my Nest system. I also would like to be able to capture the temperature reading from the actual thermostat too but that may end up not being possible. I have not began to research that part of this yet.