Test_Boiler_Communication.ino 5.37 KB
/*
 *    https://github.com/Jeroen88/EasyOpenTherm
 *    https://www.tindie.com/products/Metriot/OpenTherm-adapter/
 *
 *    Test_Boiler_Communication is a program to test if your MCU can communicate with your OpenTherm compatible boiler
 *    Copyright (C) 2022  Jeroen Döll <info@metriot.nl>
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 *    You need an OpenTherm controller that you can buy at my Tindie store,
 *    Connect the two boiler wires to the OpenTherm controller pins marked OT. The order is not important.
 *    Connect the OpenTherm controller to your microcontroller's power (3v3) and ground (GND) pins.
 *    Connect the OpenTherm TXD pin to the microcontroller's pin defined by #define OT_RX_PIN.
 *    Connect the OpenTherm RXD pin to the microcontroller's pin defined by #define OT_TX_PIN.
*/



#include <Arduino.h>

#include <EasyOpenTherm.h>


#define OT_RX_PIN (34)
#define OT_TX_PIN (17)


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("\n\nStarted");
  delay(5000);
}


void loop() {
  // put your main code here, to run repeatedly:
  static OpenTherm master(OT_RX_PIN, OT_TX_PIN);        // Create an OpenTherm master (is thermostat; boiler is slave) with GPIO34 to receive data from boiler and GPIO17 to send data to boiler
  
  // First try to connect to the boiler to read it's capabilities. The boiler returns an 8 bit slaveFlags and each bit has a meaning. The bits are defined in enum class OpenTherm::CONFIGURATION_FLAGS
  // The slaveMemberIDCode identifies the manufacturer of the boiler
  uint8_t slaveFlags;
  uint8_t slaveMemberIDCode;
  if(master.read(OpenTherm::READ_DATA_ID::SLAVE_CONFIGURATION, slaveFlags, slaveMemberIDCode)) {      // Mandatory support
    Serial.println("Your setup is working! A frame was send to the boiler and the boiler responded with a valid frame.");
    Serial.printf("Slave configuration flags is 0x%02x, slave member ID is %d (0x%02x).\n", slaveFlags, slaveMemberIDCode, slaveMemberIDCode);
    Serial.println("Here is the meanining of each bit in these flags:");
    if(slaveFlags & uint8_t(OpenTherm::CONFIGURATION_FLAGS::SLAVE_DHW_PRESENT)) Serial.println("DHW present"); else Serial.println("DHW not present");
    if(slaveFlags & uint8_t(OpenTherm::CONFIGURATION_FLAGS::SLAVE_CONTROL_TYPE)) Serial.println("Control type on/off"); else Serial.println("Control type modulating");
    if(slaveFlags & uint8_t(OpenTherm::CONFIGURATION_FLAGS::SLAVE_COOLING)) Serial.println("Cooling supprted"); else Serial.println("Cooling not supported");
    if(slaveFlags & uint8_t(OpenTherm::CONFIGURATION_FLAGS::SLAVE_DHW)) Serial.println("DHW storage tank"); else Serial.println("DHW instantaneous or not-specified"); 
    if(slaveFlags & uint8_t(OpenTherm::CONFIGURATION_FLAGS::SLAVE_LOW_OFF_PUMP_CTRL)) Serial.println("Low off and pump control not allowed"); else Serial.println("Low off and pump control allowed");
    if(slaveFlags & uint8_t(OpenTherm::CONFIGURATION_FLAGS::SLAVE_CH2_PRESENT)) Serial.println("CH2 present"); else Serial.println("CH2 not present");
  } else {
    slaveFlags = 0;

    if(master.error() == OpenTherm::ERROR_CODES::UNKNOWN_DATA_ID) {
      // Valid data is received but the for boilers mandatory DATA-ID OpenTherm::READ_DATA_ID::SLAVE_CONFIGURATION is not recognised. This is not a boiler but another device!
      Serial.println("Your setup is working correctly but the remote device is not a boiler.");
      Serial.println("Look in EasyOpenTherm.h for the HVAC_SLAVE_CONFIGURATION or SOLAR_SLAVE_CONFIGURATION\n DATA-ID and the corresponding master and slave flags.");
    } else {
      // No data or invalid data received
      Serial.println("Your setup is not working yet. Please check:");
      Serial.println("Is the OpenTherm controller connected to the boiler using two wires? The order of the wires is not important.");
      Serial.println("Is the OpenTherm controller correctly powered? The GND pin should be connected to the GND pin of the\n microcontroller and the 3v3 pin to the 3v3 pin of the microcontroller.");
      Serial.printf("Is the OpenTherm controller TxD pin connected to the microcontroller's Rx pin as specified by\n #define OT_RX_PIN? Currently this pin is defined as %d.\n", OT_RX_PIN);
      Serial.printf("Is the OpenTherm controller RxD pin connected to the microcontroller's Tx pin as specified by\n #define OT_TX_PIN? Currently this pin is defined as %d.\n", OT_TX_PIN);
      Serial.printf("Is the microcontroller's Tx pin (currently pin %d} not an 'input only' pin?\n", OT_TX_PIN);
      Serial.printf("Is in your software the OpenTherm object defined as OpenTherm master(OT_RX_PIN, OT_TX_PIN);\n Currently this expands to OpenTherm master(%d, %d);\n", OT_RX_PIN, OT_TX_PIN);
      Serial.println("\n");
    }
  }

  // Wait 5 secs and try again
  delay(5000);
}