bertmelis / VitoWiFi

Communicate with Viessmann boilers using the optolink for ESP8266 and ESP32
MIT License
118 stars 39 forks source link

ESP32 Communication issue #70

Closed SReub closed 2 years ago

SReub commented 2 years ago

Hi,

I'm having problems to establish communication with the heater controller. When I attach the optolink nothing happens, serial monitor shows setup finished but then no data communication happens. I tried rebooting my heater system (required or not?) with ESP32 attached but that makes no difference. I'm not that familiar with serial communications so I'm having a hard time to debug this problem, could anyone assist based on my setup & info below? Is there a way to gain more insight in what could be failing? Any help/feedback would be much appreciated, thanks a lot!

Installation specifics

IMG_3546

/*

This example defines three datapoints.
The first two are DPTemp type datapoints and have their own callback.
When no specific callback is attached to a datapoint, it uses the global callback.

Note the difference in return value between the callbacks:
for tempCallback uses value.getFloat() as DPTemp datapoints return a float.
globalCallback uses value.getString(char*,size_t). This method is independent of the returned type.

*/
#include <Arduino.h>
#include <VitoWiFi.h>

VitoWiFi_setProtocol(P300); //P300

DPTemp outsideTemp("outsideTemp", "boiler", 0x5525);
DPTemp boilerTemp("boilertemp", "boiler", 0x0810);
//DPStat pumpStat("pump", "heating1", 0x2906);

void tempCallbackHandler(const IDatapoint& dp, DPValue value) {
  float fahrenheit = 0;
  fahrenheit = (5.0 / 9) * (value.getFloat() + 32);
  Serial.print(dp.getGroup());
  Serial.print(" - ");
  Serial.print(dp.getName());
  Serial.print(": ");
  Serial.println(fahrenheit, 1);  // print with 1 decimal
}

void globalCallbackHandler(const IDatapoint& dp, DPValue value) {
  Serial.print(dp.getGroup());
  Serial.print(" - ");
  Serial.print(dp.getName());
  Serial.print(" is ");
  char value_str[15] = {0};
  value.getString(value_str, sizeof(value_str));
  Serial.println(value_str);
}

void setup() {
  outsideTemp.setCallback(tempCallbackHandler);
  boilerTemp.setCallback(tempCallbackHandler);
  VitoWiFi.setGlobalCallback(globalCallbackHandler);  // this callback will be used for all DPs without specific callback
                                                      // must be set after adding at least 1 datapoint
  VitoWiFi.setup(&Serial, 16, 17);  // RX then TX number
  Serial.begin(115200);
  Serial.println(F("Setup finished..."));
}

void loop() {
  static unsigned long lastMillis = 0;
  if (millis() - lastMillis > 60 * 1000UL) {  // read all values every 60 seconds
    lastMillis = millis();
    VitoWiFi.readAll();
  }
  VitoWiFi.loop();
}

17:05:55.270 -> mode:DIO, clock div:1 17:05:55.270 -> load:0x3fff0018,len:4 17:05:55.270 -> load:0x3fff001c,len:1044 17:05:55.270 -> load:0x40078000,len:10124 17:05:55.374 -> load:0x40080400,len:5856 17:05:55.374 -> entry 0x400806a8 17:05:55.374 -> Setup finished...

To check the opto link I tested the IR led with a simple blink sketch and that worked fine, same thing with the IR transistor.

bertmelis commented 2 years ago

It's been a while since I used this lib because I don't have a Viessmann heater at the moment. So I can't test anything unfortunately. Anyway, I'm happy to help.

First things first, could you enable logging:

VitoWiFi.setLogger(Printer*) so vitoWiFi can print messages for debugging purposes. VitoWiFi.enableLogger() or .disableLogger() enables or disables logging

SReub commented 2 years ago

Bert,

When adding this logger I get a compiling error saying "Identifier Printer is undefined".

src/main.cpp: In function 'void setup()': src/main.cpp:42:22: error: 'Printer' was not declared in this scope VitoWiFi.setLogger(Printer); ^~~ src/main.cpp:42:22: note: suggested alternative: 'Print' VitoWiFi.setLogger(Printer); ^~~ Print src/main.cpp:42:30: error: expected primary-expression before ')' token VitoWiFi.setLogger(Printer*);

Code:

void setup() { VitoWiFi.setLogger(Printer*); VitoWiFi.enableLogger();

bertmelis commented 2 years ago

Oh, I see the example has some flaws.

ESP32 has 3 UARTs and Arduino defines them as Serial, Serial1 and Serial2. USB is connected to Serial so better not use this. If I understand your picture, you use Serial2 to connect to your heater?

Then you should do (left out all the code, so cut and paste appropriately):

VitoWiFi.setup(&Serial2, 16, 17);  // I'm not 100% sure about the pin numbers
VitoWiFi.setLogger(&Serial);
VitoWiFi.enableLogger();
SReub commented 2 years ago

Great, I now get readings in the serial monitor. Thanks a lot!!

One more question: I have a global callback defined and I'm using VitoWiFi.readAll(); to read the bus, why do I only see the specific messages defined in the setup() and not all messages on the bus?

// Serial monitor: Setup finished... READ outsideTemp READ boilertemp READ 4105000155250282 ack RCV 4107010155250204018a ack DP outsideTemp succes boiler outsideTemp: 26.0 READ 4105000108100220 ack RCV 41070101081002110135 ack DP boilertemp succes boiler boilertemp: 27.3

bertmelis commented 2 years ago

readAll reads all the DPs you defined in your program. So in your code, you defined outsideTemp and boilerTemp and that is what is being read. You have to define more if you want to read more. The optolink isn't an internal bus of the system, there isn't any traffic unless you request data.

The files in the /docs folder contain a large amount of datapoint for your system. I also have (had) a Vitotronic 200 with HO1C controller, a lot of the datapoints are correct.