schnef / dsmr-mqtt

DSMR P1 MQTT bridge (ESP8266)
MIT License
1 stars 2 forks source link

dsmr.available() remains false #2

Open ErwinP opened 3 years ago

ErwinP commented 3 years ago

Hi,

I'm trying to replicate your project and as I'm a novice on the matter, I bought the exact same Adafruit ESP8266 breakout board.

Things seem te work as expected (I get MQTT messages at given intervals), but I'm not able to communicate with the P1 port: dsmr.available() remains False. I am using the dsmr library adjusted for Belgium so the problem could be there, but just to check that hardwarematically everything is oke, I wondered if his seupt is oke?

Setup

Orange -> P1 #5 Yellow -> P1 #3 green (GPIO #4) -> P1 #2

The two pins at the right are used to hook up an external power source.

Thank you in advance, Erwin

schnef commented 3 years ago

This is what I use in my project which corresponds to your setup as far as I can see. So the wiring seems to be OK. The only difference is that I use the RX connection close to the #4 pin instead of the RX on the header.

RJ11 pinout P1 poort kabel

RJ11 pin to HUZZAH:

  1. Not connected
  2. black -> #4 (Request, P1_DATA_REQ)
  3. Red -> GND (Data GND)
  4. Green -> Not connected
  5. Yellow -> RX (Data)
  6. Not connected

I assume you are using the dsmr-mqtt.ino script. Is the blue led blinking or not? I am a little puzzled by you saying dsmr.available() remaining false. Also, you are getting MQTT messages, which are only send when a telegram was received and is being successively processed.

    if (reader.available()) {
      digitalWrite(LED_BLUE, ON);
      if (reader.parse(&data, &err)) {
        publish(data);
      }
      digitalWrite(LED_BLUE, OFF);
    }

In the dsmr-mqtt.ino script I call reader.available() to check for data availability and the reader is defined as P1Reader reader(&Serial, P1_DATA_REQ). Also, to enable the meter to start sending data, I call reader.enable(false).

What type of DSMR meter are you using? Which DSMR version is supported by the meter?

NB: Another issue could be that the HUZZAH I/O lines operate at 3,3 V and the P1 port is operating at 5 V. Start by connecting pin 2 of the P1 port to the 5V pin on the HUZZAH. In some posts I read that in some situations a pull-up resistor is used for the Data - RX line. Because the HUZZAH's input can handle 3.3V and NOT 5V, you may add a 1K or 2K2 pull-up resistor between RX and 3.3V.

ErwinP commented 3 years ago

Hi,

RJ11 pin to HUZZAH:

I just quadruple checkt it, and this is the case.

I assume you are using the dsmr-mqtt.ino script.

I am using that script. I should however have mentioned that I adjusted it a little bit to provide more output, both in terms of serial communication, as well as over MQTT. A such, I can follow where in the script that things are going wrong. You can check it out here.

Is the blue led blinking or not? I am a little puzzled by you saying dsmr.available() remaining false.

It is not. I specifically added some MQTT broadcast commands to check if I get past the if (reader.available()) statement, and this does not happen:

if (reader.available()) {
   pubsubClient.publish(dsmr_debug, "Reader available!")
   ...
} else {
   pubsubClient.publish(dsmr_debug, "Reader not available")
}

always results in an MQTT message stating Reader not available

In the dsmr-mqtt.ino script I call reader.available() to check for data availability and the reader is defined as P1Reader reader(&Serial, P1_DATA_REQ). Also, to enable the meter to start sending data, I call reader.enable(false).

I tried both reader.enable(false) and reader.enable(true). Moreover, I have this in the beginning of the script:

if (reader.available(true)) { // or reader.available(false)
    pubsubClient.publish(dsmr_debug, "Reader seems to be available at the start.");
    ...
} else {
   pubsubClient.publish(dsmr_debug, "Reader not available from the start.");
}

And this always results in an MQTT message Reader not available from the start.

What type of DSMR meter are you using? Which DSMR version is supported by the meter?

I have a "Sagemcom – S211 eenfasig". According to the documention, The user port is implemented in accordance with the Dutch concept, namely DSMR 5.0.2 P1.

NB: Another issue could be that the HUZZAH I/O lines operate at 3,3 V and the P1 port is operating at 5 V. Start by connecting pin 2 of the P1 port to the 5V pin on the HUZZAH. In some posts I read that in some situations a pull-up resistor is used for the Data - RX line. Because the HUZZAH's input can handle 3.3V and NOT 5V, you may add a 1K or 2K2 pull-up resistor between RX and 3.3V.

I'm not quite sure if I understand this.. As I said, this is all new to me, sorry. I however just tried to connect P1 #2 to the 5V power supply. I measured the voltage over P1#2 and P1#3 (Gnd), and confirmed that it was 5V. It however did not make a difference. In terms of the pull-up resistor, I'm quite lost here..

Already thanks a lot for your input on this matter, I really appreciate it!

EDIT

Perhaps one additonal thing: I'm using the BE variant of the dsmr library (I also opened my issue there). I'm now wondering: if this library would not be able to correctly parse the data from the P1 port, would reader.available() also fail to return true? In other words: can I distinguish between Invert RX not working versus the data is not in the correct format?

schnef commented 3 years ago

You're using serial for debugging which is also used to connect to the P1 port. Can it be that connecting the HUZZAH to both your computer and to the P1 port is the problem? Do you use Arduimo and the serial monitor? Than you probably use a fully wired connection which also uses the RX line for communicating with Arduino which I am quite certain of will interfere with the P1 connection.

Maybe, you can use this tool for debugging. After initial program load, use OTA for updating the code and leave the serial line connected to the P1 port only.

The metering device you try to make the readings from, what manufacturer and type is it? I only tested it with the Sagemcom T210-D installed here at home.

ErwinP commented 3 years ago

That would indeed be a problem, but I'm not connecting the P1 and my computer simultaniously. It is either the meter, either my computer that is connected.

I just saw that I have the Sagemcom T211.. Not quite sure what the differences are, but they can't be so different?

Anyway, yesterday, I changed the RX to the pin on the side (like you did) and tried with the original code, with and without applying 5V over the P1 data port.. with no differences, it still didn't work. I don't know if you have any thoughts?

schnef commented 3 years ago

This is frustrating! Maybe this helps:

  1. Use the software serial library to try to read from the P1 port. Install the SoftSerial library from: https://github.com/plerup/espsoftwareserial. Software serial does give garbled telegrams because it can't keep up with the P1 port, but now you should be able to check for data on the port. Copy the input from the P1 port to serial and check the Arduino's serial monitor for telegrams, maybe/probably with errors:
    
    #include <ESP8266WiFi.h>
    #include "SoftwareSerial.h"

define P1_DATA_REQ 4 // connect to 2 )request) on P1

define P1_DATA 5 // connect to 5 (data) on Pi

SoftwareSerial swSer;

void setup() { delay(2000); Serial.begin(115200); Serial.println("Serial Tester"); // Use inverse logic, see: https://www.arduino.cc/en/Reference/SoftwareSerialConstructor swSer.begin(115200, SWSERIAL_8N1, P1_DATA, P1_DATA, true, 256); pinMode(P1_DATA_REQ, OUTPUT); digitalWrite(P1_DATA_REQ, HIGH); }

void loop() { while (swSer.available() > 0) { Serial.write(swSer.read()); yield(); } }

2. Use the `dsmr-mqtt-basic.ino` script instead of the `dsmr-mqtt.ino`script. This will take the dsmr library out of the loop.
3. Check if the meter is actually outputting anything on the P1 port. For debugging, start by replacing the code from `dsmr-mqtt-basic.ino` starting at line [156](https://github.com/schnef/dsmr-mqtt/blob/a82cf04993bca5415db6fd8d32193f09c02b872b/dsmr-mqtt-basic.ino#L156) with something like (I didn't test this, but this should consume any character coming in on the serial port and making the blue led flash (I hope)) :
if (Serial.available() > 0) {
  c = Serial.read();
  digitalWrite(LED_BLUE, ON);
} else {
  digitalWrite(LED_BLUE, OFF);
}
Morris3190 commented 3 years ago

Erwin, I hope you are a aware of the fact that the data-pin from the SmartMeter is TTL-level, 5v BUT inverted logic ? So you must invert the signal with a transistor and also bring the voltage down from 5v to 3v if you want your ESP8266 to survive. I have a Siconia T211 (Fluvius) and 1 transistor and a few resistors does the trick. You can find a schematic here . You can check functionality just with PC, your Arduino serial monitor and a USB-serial converter where you only connect the RX and GND to the transistor-schematic. Of course you need to pull the Data Request pin of your smartmeter high with a small resistor to the 5V line.

schnef commented 3 years ago

@Morris3190 is right about the DATA line being inverted. But, instead of using an external hardware inverter, the "trick" in this project is to configure the esp8266's UART RX pin to operate in inverted mode. In the UART control register, you can set UCRXI bit for inverted input. Also see https://github.com/esp8266/Arduino/issues/4896.

The DATA output of the DSMR is an open collector output, so you can connect it to the esp8266 without any problem. See Figure 5-2 (p7) and paragraph 5.7.2 (p13). An open collector output will only operate at the voltage level you supply. The only issue is that the DATA line is specified to be operated at TTL levels, but it may well work at 3.3V as well. It does so with my meter. Another issue is that the RX pin must 'drive' the open collector DATA output. Again, in my situation it does so. If it doesn't work, one can try to add a 1K pull-up resistor from the RX pin to 3.3V to drive the meter's open collector output.

The DATA REQUEST line must be kept high to enable the P1 port (paragraph 5.7.1 in the specs (p12). When I connect DATA REQUEST to 3.3V from one of the GPIOs of the esp8266, it does work, but it might be necessary to connect it to 5V. Use a pull-up resistor in that case of 1K from 5V to the DATA REQUEST pin to enable the port.

The hardware setup used here does operate outside the specifications given in the specs, but it might very well work in most cases. In combination with the Sagemcom T210-D, it works very reliable for over a year now.