mudman
March 9, 2020, 4:30pm
1
Hi just wanted to share my latest project with you. MQTT trv based on the very cheep non Bluetooth EQ3 trv.
So let’s first tare one down
the original control board was replaced with a Wemos D1 mini. Since the motor is only 2 wire a L298N was used to control direction and a max471 used to sense motor stall current as the motor does not have a limit switch.
A few picks of the components used
Arduino code to follow in the next post
4 Likes
mudman
March 9, 2020, 4:38pm
2
#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#define LED 2 //wemos D1 led pin
#define Motorforward 4 // H bridge motor forrward
pin
#define Motorbackward 5 // H bridge motor
backwards pin
#define max471In A0 // input for max471
current mon pin
#define MQTT_CLIENT "mqtt_trv_1" // mqtt client_id (Must be
unique for each TRV)
#define MQTT_SERVER "SERVER IP" // mqtt server
#define MQTT_PORT 1883 // mqtt port
#define MQTT_TOPIC "home/trv_1" // mqtt topic (Must be
unique for each TRV)
#define MQTT_USER "*******" // mqtt
user
#define MQTT_PASS "********" // mqtt password
#define WIFI_SSID "******" // wifi ssid
#define WIFI_PASS "*****" // wifi password
#define VERSION "\n\n------------------ MQTT TRV v1.0
------------------"
bool rememberMotorState = true; // If
'true' remembers the state of the Motor before power loss.
bool sendStatus = false; // (Do not
Change)
bool requestRestart = false; // (Do not
Change)
int kUpdFreq = 1; // Update
frequency in Mintes to check for mqtt connection
int kRetries = 10; // WiFi
retry count. Increase if not connecting to router.
int lastMotorState; // (Do not
Change)
int RawValue= 0; // (Do not
Change)
float Current = 0; // (Do not
Change)
unsigned long TTasks; // (Do not
Change)
unsigned long count = 0; // (Do not
Change)
extern "C" {
#include "user_interface.h"
}
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient, MQTT_SERVER, MQTT_PORT);
void callback(const MQTT::Publish& pub) {
if (pub.payload_string() == "stat") {
}
else if (pub.payload_string() == "on") {
digitalWrite(LED, LOW);
trv_on();
}
else if (pub.payload_string() == "off") {
digitalWrite(LED, HIGH);
trv_off();
}
else if (pub.payload_string() == "reset") {
requestRestart = true;
}
sendStatus = true;
}
void setup() {
pinMode(max471In, INPUT);
pinMode(Motorforward, OUTPUT);
pinMode(Motorbackward, OUTPUT);
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);
analogWrite(Motorforward, 0);
analogWrite(Motorbackward, 0);
Serial.begin(115200);
EEPROM.begin(8);
lastMotorState = EEPROM.read(0);
if (rememberMotorState && lastMotorState == 1) {
digitalWrite(LED, LOW);
trv_on();
}
if (rememberMotorState && lastMotorState == 0) {
digitalWrite(LED, HIGH);
trv_off();
}
mqttClient.set_callback(callback);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
Serial.println(VERSION);
Serial.print("\nUnit ID: ");
Serial.print("esp8266-");
Serial.print(ESP.getChipId(), HEX);
Serial.print("\nConnecting to "); Serial.print(WIFI_SSID);
Serial.print(" Wifi");
while ((WiFi.status() != WL_CONNECTED) && kRetries --) {
delay(500);
Serial.print(" .");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println(" DONE");
Serial.print("IP Address is: "); Serial.println(WiFi.localIP());
Serial.print("Connecting to
");Serial.print(MQTT_SERVER);Serial.print(" Broker . .");
delay(500);
while
(!mqttClient.connect(MQTT::Connect(MQTT_CLIENT).set_keepalive(90).set_auth(MQTT_USER,
MQTT_PASS)) && kRetries --) {
Serial.print(" .");
delay(1000);
}
if(mqttClient.connected()) {
Serial.println(" DONE");
Serial.println("\n---------------------------- Logs
----------------------------");
Serial.println();
mqttClient.subscribe(MQTT_TOPIC);
blinkLED(LED, 40, 8);
}
else {
Serial.println(" FAILED!");
Serial.println("\n
");
Serial.println();
}
}
else {
Serial.println(" WiFi FAILED!");
Serial.println("\n
");
Serial.println();
}
}
void loop() {
mqttClient.loop();
timedTasks();
checkStatus();
}
void get_current() {
RawValue = analogRead(max471In);
Current = (RawValue * 5.0 )/ 1024.0;
Serial.print("Current = "); //
shows the voltage measured
Serial.print(Current,3); //3 digits
after decimal point
Serial.println(" amps DC"); //3
digits after decimal point
}
void trv_on(){
get_current();
while(Current < 0.150){
Serial.println("motorr moving backwads");
analogWrite(Motorforward, 0);
analogWrite(Motorbackward, 1023);
delay(1000);
get_current();
if(Current > 0.150){
analogWrite(Motorforward, 0);
analogWrite(Motorbackward, 0);
Serial.println("motor stop");
}
}
}
void trv_off(){
get_current();
while(Current < 0.150){
Serial.println("motorr moving forwad");
analogWrite(Motorforward, 1023);
analogWrite(Motorbackward, 0);
delay(1000);
get_current();
if(Current > 0.150){
analogWrite(Motorforward, 0);
analogWrite(Motorbackward, 0);
Serial.println("motor stop");
}
}
}
void blinkLED(int pin, int duration, int n) {
for(int i=0; i<n; i++) {
digitalWrite(pin, HIGH);
delay(duration);
digitalWrite(pin, LOW);
delay(duration);
}
}
void checkConnection() {
if (WiFi.status() == WL_CONNECTED) {
if (mqttClient.connected()) {
Serial.println("mqtt broker connection . . . . . . . . . . OK");
}
else {
Serial.println("mqtt broker connection . . . . . . . . . . LOST");
requestRestart = true;
}
}
else {
Serial.println("WiFi connection . . . . . . . . . . LOST");
requestRestart = true;
}
}
void checkStatus() {
if (sendStatus) {
if(digitalRead(LED) == LOW) {
if (rememberMotorState) {
EEPROM.write(0, 1);
}
mqttClient.publish(MQTT::Publish(MQTT_TOPIC"/stat",
"on").set_retain().set_qos(1));
Serial.println("TRV . . . . . . . . . . . . . . . . . . ON");
trv_on();
} else {
if (rememberMotorState) {
EEPROM.write(0, 0);
}
mqttClient.publish(MQTT::Publish(MQTT_TOPIC"/stat",
"off").set_retain().set_qos(1));
Serial.println("TRV . . . . . . . . . . . . . . . . . . OFF");
trv_off();
}
if (rememberMotorState) {
EEPROM.commit();
}
sendStatus = false;
}
if (requestRestart) {
blinkLED(LED, 400, 4);
ESP.restart();
}
}
void timedTasks() {
if ((millis() > TTasks + (kUpdFreq*60000)) || (millis() < TTasks)) {
TTasks = millis();
checkConnection();
}
}
1 Like
mudman
March 9, 2020, 4:54pm
3
The next plan is to add oled screen to replace the LCD. Just waiting on the parts to arrive. Plan is to display current room temp and valve status
2 Likes
Tim_Heaton
(Tim Heaton)
September 9, 2020, 9:04pm
4
hove you got any further with this? i am intrigued i was hoping to do something similar and add dht22 for room temps
sachast
November 14, 2020, 8:52pm
5
I bought this TRV to play with too.
I had 2 ideas :
Remove the PCB and do a new one with an ESP
Reprogram the STM and add a UART between an added ESP and the STM
Did you made some improvements ?
the old is a good idea too ! I’ll have a look. Do you have a reference ?
homonto
(Zygfryd Homonto)
September 19, 2022, 7:20pm
6
I am wondering if you are still using it 2 years later or you moved to something else. I am looking for smart TRV that can be locally controlled only but apparently I cannot find anything - all is closed source and cloud only and expensive as well. Let me know if you are still there please
Spiro
September 19, 2022, 9:06pm
7
The eq3 can be locally controlled by Bluetooth with no need for the phone app nor to be modified. Many of us have been struggling to get them to work past 2 months due to changes in HA. I have them working using Bluetooth on TASMOTA on esp32.
homonto
(Zygfryd Homonto)
September 19, 2022, 9:36pm
8
Thx, I was thinking about putting ESP there instead of the original board - this way ESPhome and no issues, right? or even DIY code in Arduino or so
mhaas
(Michael Haas)
September 20, 2022, 6:05am
9
Back in the day, I was dabbling a bit with building a battery powered ESP8266 temperature wensor. My takeaway was: I could get a battery life of a few months even with a very efficient power regulator and wake up from deep sleep every 10 minutes.
What I am saying: if you plug in a D1 mini, the battery life will be much shorter than the originally advertised 1 or 2 years