-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAutohome_Fan_Controller.ino
168 lines (152 loc) · 5.99 KB
/
Autohome_Fan_Controller.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "env.h"
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
// wifi
WiFiClient espClient;
PubSubClient client(espClient);
static long timeout = 0;
char msg[50];
float temperature = 0;
volatile byte interruptCounter = 0;
bool relayState = 0;
// temperature sensor
int resolution = 9;
long temperatureWaitTime = (750/ (1 << (12-resolution)));
long temperatureRequestedTime = 0;
// pins
const int led = 13;
const int relay = 12;
const int button = 0;
const int temperatureSensorPin = 1; // 1
// function prototypes
void setupWifi();
void callback(char* topic, byte* payload, unsigned int length);
void reconnectMQTT();
void handleInterrupt();
OneWire oneWire(temperatureSensorPin);
DallasTemperature temperatureSensor(&oneWire);
void setup(void){
pinMode(led, OUTPUT);
pinMode(relay, OUTPUT);
pinMode(button, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(button), handleInterrupt, RISING);
//Serial.begin(115200);
setupWifi();
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
temperatureSensor.begin();
temperatureSensor.setWaitForConversion(false);
temperatureSensor.setResolution(resolution);
//Serial.println(sensors.getResolution(tempSensor), DEC);
temperatureSensor.requestTemperatures();
timeout = millis() + 10000;
}
void loop(void){
if (!client.connected()) {
reconnectMQTT();
}
client.loop();
long now = millis();
if ((long)(now - timeout) >= 0) {
temperatureSensor.requestTemperatures();
temperatureRequestedTime = millis();
timeout = now + 60000;
// delay the remaining time that the sensor takes to finish converting
delay(MAX(temperatureRequestedTime - millis(), 0));
//Serial.println(temperatureWaitTime);
//Serial.print("temperature = ");
//Serial.println(temperature);
//Serial.print("devices: ");
//Serial.println(temperatureSensor.getDeviceCount());
temperature = temperatureSensor.getTempCByIndex(0);
temperatureRequestedTime = 0;
//snprintf (msg, 50, "hello world #%ld", value);
//Serial.print("Publish message: ");
//Serial.println(temperature);
dtostrf(temperature, 3, 1, msg);
client.publish("heater/fan/temperature", msg);
//Serial.print("wifi level: ");
//Serial.println(WiFi.RSSI());
}
if (interruptCounter > 0){
// Change state only if interruptCounter has changed by odd amount
if (interruptCounter % 2){
//Serial.println("relay triggered");
// location/device?/data
client.publish("heater/fan/status", relayState ? "1" : "0");
}
interruptCounter = 0;
}
}
void setupWifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
digitalWrite(led, LOW);
delay(500);
digitalWrite(led, HIGH);
delay(500);
}
//Serial.println("Connected to wifi");
}
void callback(char* topic, byte* payload, unsigned int length) {
// Serial.print("Message arrived [");
// Serial.print(topic);
// Serial.print("] ");
// Serial.println(length);
// for (int i = 0; i < length; i++) {
// Serial.print((char)payload[i]);
// }
//Serial.println();
// If we get a message on heater/fan/control, update the relay
if (strcmp(topic,"heater/fan/control") == 0) {
//Serial.println("topic is /heater/fan");
if ((char)payload[0] == '1'){
digitalWrite(led, LOW);
digitalWrite(relay, HIGH);
relayState = 1;
//Serial.println("relay on");
} else if ((char)payload[0] == '0') {
digitalWrite(led, HIGH);
digitalWrite(relay, LOW);
relayState = 0;
//Serial.println("relay off");
} else {
client.publish("debug", "unrecognized fan command");
}
}
}
void reconnectMQTT() {
// Loop until we're reconnected
while (!client.connected()) {
//Serial.print("Attempting MQTT connection...");
String clientId = "Heater Fan Controller";
if (client.connect(clientId.c_str(), NULL, NULL, "heater/fan/temperature", 0, 0, "0")) {
//Serial.println("connected");
client.subscribe("heater/fan/control");
} else {
//Serial.print("failed, rc=");
//Serial.print(client.state());
//Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
// Turn relay on when button is pressed, debounce, and increment interruptCounter
// This is not done in the main loop because we can be searching for wifi
// but still want to be able to turn on the relay with the button
void handleInterrupt() {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
// If interrupts come faster than 200ms, assume it's a bounce and ignore
if (interruptTime - lastInterruptTime > 200) {
interruptCounter++;
relayState =! relayState;
digitalWrite(relay, relayState ? HIGH : LOW);
digitalWrite(led, relayState ? LOW : HIGH);
}
lastInterruptTime = interruptTime;
}