Is there demand for adding a new serial binding for DIY devices?

Tags: #<Tag:0x00007f616de98628> #<Tag:0x00007f616de983d0> #<Tag:0x00007f616de982b8>

Hi I have serial binding with simple serial binary protocol. It can be used for communication via serial port (RS232, RS485,…) with DIY devices like Arduino.

Binding itself support all openhab datatypes.

Protocol support 2 modes for reading data from connected devices. First one is OnScan at which all data are reading cyclically. Second one is OnChange. In this mode each device is polled whether has new data and then sends data to openHAB.

Protocol example:

Check new data (4 bytes frame)

| 0 | 1 | 2 | 3 | 

0 - device address
1 - message type - Check new data (0xD0)
2 - 0x00
3 - CRC8

Write word (7 bytes frame)

| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 

0 - device address
1 - message type - Write word (0xDB)
2 - address low byte
3 - address high byte
4 - data low byte
5 - data high byte
6 - CRC8
1 Like

Hi there - Good timing for you to post this… I am currently prototyping some Arduino devices, which will be connected to OpenHab via RS485. To date I have been using ModBus RTU interface from OpenHab to Arduino. I guess the upside of this approach, is that I am using a Standard Protocol for interfacing. And it sort of works.

But the downside, is that its probably a whole lot more complicated than it needs to be, and has taken me a long time to figure out whats what… And it seems to be very timing sensitive (e.g. when reading a dallas temperature probe, will get Modbus timeouts for a short moment - I know why, but have been too busy to sort…)

Which is perhaps where your idea has some real merit. Direct use of OpenHAB datatypes, without having to concern oneself with intermediary ModBus details (e.g. coil/holding etc), Perhaps also less configuration to be had in openhab.cfg, with the bulk of the definitions in the items file?? This could mean easier setup for users (without having to have a ModBus protocol reference open in another window… :slight_smile: ).

Do you have a corresponding sketch implementing the protocol for the Arduino side?

Cheers - Glen

1 Like

Hi Glen,

right now I am putting this binding together with documentation to git. You can find it here: https://github.com/docbender/openHAB-SimpleBinary . I’ll put there also my example of sketch for Arduino.

I know that protocol isn’t standard as Modbus and you can’t connect it to whatever, but main advantage is low communication overhead and simple conversion OpenHAB datatypes into basic datatypes as byte, word, dword, … so it should be easy to handle it in your hardware.

So if you are interested look at my git. Will be completed within a few days.

Hello
very nice work and exactly that what I was looking for. Thank you very much! I implemented the code on a Rasperry Pi and an Arduino Mega.
For a first attempt, I changed the openhab demo house by only one item which communicates over RS485 and simpleBinary:

Switch Light_GF_Living_Table2 "Table" (GF_Living, Lights) { simplebinary="port:1:1:byte:O" }

and inserted this line in the setup scope of arduino sketch:

items->initItem(0,1,BYTE,executeData);

This works!

But openhab is polling every 2 seconds for new data and gets timeouts (Log: Receiving data timeouted)!
Arduino receives 1 D0 0 D1 (Device Command 0 CRC8) and runs into this code:

/// Process data received by UART 
///
void simpleBinary::processSerial()
{
    while (Serial2.available() > 0) 
    {
      int data = Serial2.read();
      
      Serial.print(data, HEX); //for debugging with Serial Monitor: here I get 1 D0 0 D1 every 2nd second
      Serial.print(" ");
      serbuf[serbuflen++] = data;
    }
    Serial.println("");
    
    if(serbuflen > 3)
    {
      if(serbuf[0] == _uartAddress)    
      {
        int address;
        char crc;
        
        switch(serbuf[1])
        {
          //new data
          case (char)0xD0:
            if(serbuf[2] == 0x00)
            {
               crc = CRC8::evalCRC(serbuf,3);

               if(crc != serbuf[3])
                  sendWrongData(serbuf[3]);
                else
                  checkNewData();
            } 

The call of checkNewData() calls sendNoData().

void simpleBinary::checkNewData()
{
  //check all items
  for(int i=0;i<_size;i++)
  {    
    //send data first finded item
    //itemData it = (*items)[i];
    if(_data[i].hasNewData())
    {
      sendData(&(_data[i]));
      
      return;
    }    
  }

  //no new data available
  sendNoData();
}

/// Send answer that there are no new data
void simpleBinary::sendNoData()
{
    char data[4];

    data[0] = _uartAddress;
    data[1] = 0xE2;
    data[2] = 0x0;
    data[3] = CRC8::evalCRC(data,3);
    
    digitalWrite(SSerialTxControl, RS485Transmit);
    Serial2.write(data,4);
    delay(10);
    digitalWrite(SSerialTxControl, RS485Receive);
}

As I understood, openhab master should receive the information, that there is no new data on slave by this code. Do you have any idea what I’m doing wrong as I get these timeouts?

Many greetings

Andreas

1 Like

Hi Andreas,
so your issue is that Arduino receives data but answer does not arrive into binding. Right?

At first I would recommend to use latest version of binding.

Your code and configuration looks OK. In binding 2s timeout is violated when no data or bad data are received.

Have you tried to use serial terminal (like RealTerm) instead of binding to see if there is communication between devices?

Also it would be good to turn on a more detailed logging. Either by run openHAB in debug mode or add log settings to logback.xml like this (behind <configuration scan="true">) :

   <appender name="SBFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
     <file>logs/simplebinary.log</file>
     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       <!-- weekly rollover and archiving -->
       <fileNamePattern>logs/sb-%d{yyyy-MM-dd}.log.zip</fileNamePattern>
       <!-- keep 1 day of history -->
       <maxHistory>1</maxHistory>
     </rollingPolicy>
     <encoder>
       <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{30}[:%line]- %msg%n%ex{5}</pattern>
     </encoder>
   </appender>
   <!-- Change DEBUG->TRACE for even more detailed logging -->
   <logger name="org.openhab.binding.simplebinary" level="DEBUG" additivity="false">
     <appender-ref ref="SBFILE" />
   </logger>

Then you can see sent and received data too.

What kind of connection do you use? RS485 line, RS232 or USB converter?

This is all a little above my head, but let me explain what I’m trying to do and ask if this binding might help me.

I have a whole home audio system that I use an Android app to operate. The app connects via wifi to to a serial gateway. I’ve figured out how to log into the gateway and use the web interface to send hex codes via web sockets to perform certain functions.

Would this binding allow me to operate my gateway via ethernet (e.g. I specify a URL), or does this only work for devices connected to a serial port?

Thanks! (and sorry if this is a dumb question)

Hello @joefrank251,

SimpleBinary binding can connect to devices over serial port or over ethernet. In ethernet mode binding act as TCP server so device must initiate connection. In both cases binding specific protocol is used.

If I understand it well, you need to connect openHAB to your serial gateway over ethernet. So if you cannot reprogram gateway to SimpleBinary protocol, maybe way to connect your gateway can be TCP binding.

Hello Vita, are you planning to migrate the SimpleBinary Binding official to an openHAB 2.x Binding?

Hi,
in the near future i don’t plan move to OH2. Specially when it works as it is now.

    1. 2018 14:47, 14:47, Modulo Fs bot@community.openhab.org napsal/a:

Hello again! Now ive switched to openhab 2.2 with the openhabian installation on a raspberrypi 3. But now i get some problems connecting with my slave over rs485 serial. The SimpleBinary Binding always respons a timeout error for the communication with my slave. I ve checkt physical the communication over the rs485 line and the communication looks ok. The master sends a 0xD0 message and the slave answers with an 0xE2 message. The answer from the slave comes with a delay of only 150 microseconds! My question is now, could this very short delay cause the problem with the timeout error?
Iam not at home at the moment so i cant make a logdump. Maybe i can post one tomorrow.

Hi,
it is weird that it was working before. But as you wrote, you have short response delay and that could be problem if you use RS485 flow control provided by RTS (forceRTS parameter in configuration).
The RTS signal cancellation occurs when outputbuffer is empty. But in linux (Ubuntu) I can not count with the event OUTPUT_BUFFER_EMPTY so I must implemented there time delay 1ms(system tick change) before RTS signal is turned off. So if you use RTS control you can try to delay your response from slave

Ok, now ive got the problem, but sadly no solution. I’am using a USB to RS485 Converter like this:


The Command “lsusb” says to me its a: “QinHeng Electronics HL-340 USB-Serial adapter”
I’ve disassembled the device and measured the Signal who switches the MAX485 between Transmit and Receive. The Signal is always at High-Level. So the converter can only transmit data to the RS485 line. I’ve tried all config possibilities in the SimpleBinary config file: forceRTS; forceRTSInv and without.
Does anyone knows of this problem by the RaspberryPi 3 and openHABian?? At my old System (RaspberryPi 1 and Raspbian Wheezy) the converter works correctly.

I don’t how your converter handle flow control pin, but converter that i use does not need handle RTS signal (forceRTS option not needed).

Maybe you can try to send 0xD0 command from serial terminal on different computer to see if converter works correctly

UPDATE!

I’ve bought a new USB to RS485 Converter and it sems to WORK!! Maybe the old Converter gets damaged at the connection change from the old RasperryPi 1 to the new RaspberryPi3! What a dump failure!!! Ouh man this problem has cost me a lot of nerves…