orgua / OneWireHub

OneWire slave device emulator
GNU General Public License v3.0
343 stars 86 forks source link

Loxone and Wemos D1 #65

Closed gahujipo closed 1 year ago

gahujipo commented 5 years ago

I tried to emulate a DS2438 on a Wemos D1 and find the "sensor" with Loxone. The Wemos D1 has only 3,3V pins so I used a level shifter to rise the signal to 5V. But it couldn't be found.

My wiring scheme is this: 1wire-scheme

My current code is this

#include "OneWireHub.h"
#include "DS2438.h"

constexpr uint8_t pin_led{LED_BUILTIN};
constexpr uint8_t pin_onewire{0}; // Arduino D3

auto hub = OneWireHub(pin_onewire);
auto ds2438 = DS2438(DS2438::family_code, 0x00, 0x00, 0x38, 0x24, 0xDA, 0x00); // todo what hex code for serial number

// the setup function runs once when you press reset or power the board
void setup()
{
    Serial.begin(115200);
    Serial.println("OneWire-Hub DS2438 BME680");

    pinMode(pin_led, OUTPUT);

    // Setup OneWire
    hub.attach(ds2438);

    Serial.print("Test: set Temperature in float 38 deg C: ");
    ds2438.setTemperature(38.0f);  // can vary from -55 to 125deg
    Serial.println(ds2438.getTemperature());
}

// the loop function runs over and over again until power down or reset
void loop()
{
    // following function must be called periodically
    hub.poll();

    // Blink triggers the state-change
    if (blinking())
    {
        static float    temp = 10.0;
        static uint16_t volt_10mV = 10;
        static uint16_t current = 10;

        if ((temp += 0.05) > 30.0) temp = 10.0;
        if ((volt_10mV++) > 200) volt_10mV = 10;
        if ((current++)   > 200) current = 10;

        ds2438.setTemperature(temp);
        ds2438.setVoltage(volt_10mV);
        ds2438.setCurrent(current);

        Serial.println(temp);
    }
}

bool blinking(void)
{
    const  uint32_t interval = 2000;          // interval at which to blink (milliseconds)
    static uint32_t nextMillis = millis();     // will store next time LED will updated

    if (millis() > nextMillis)
    {
        nextMillis += interval;             // save the next time you blinked the LED
        static uint8_t ledState = LOW;      // ledState used to set the LED
        if (ledState == LOW)    ledState = HIGH;
        else                    ledState = LOW;
        digitalWrite(pin_led, ledState);
        return 1;
    }
    return 0;
}

Is this correct or am I missing something?

gahujipo commented 5 years ago

I followed the steps in the README and set up an emulated DS18B20 which works, even more than 8 hours in line. After that I was even able to stabilise the communication so that my master was able to find DS2438. I was able to get data from the emulated DS2438 once, but after that my master isn't able to get further data. The DS2438 remains discoverable, but doesn't return any data. I tested this with an interval of 30 seconds between each read cycle. Do you have a hint what I could try else?

gahujipo commented 5 years ago

After adjusting the following values

raintonr commented 3 years ago

The DS2438 remains discoverable, but doesn't return any data.

I see exactly the same thing here with Loxone system.

I discovered a different version of DS2438. The code wasn't on Github but I copied it for a very basic MQ135 sensor:

https://github.com/raintonr/MQ135As1W

This works perfectly. Been stable here for months.

However, I recently wanted to do something more complex involving using setVADVoltage and setVDDVoltage (new methods in code linked above). When trying to use them both they often get reported as zero for some reason. Will try and figure that out.

raintonr commented 3 years ago

On this topic, I found the following very useful page describing DS2438 communications and the mechanism to read VAD or VDD:

https://eds.zendesk.com/hc/en-us/articles/214484863-Working-with-the-DS2438-using-the-HA7E-HA7S

When a DS2438 is configured in Loxone it always reads both VAD and VDD. It's true to say, that due to other limitations in Loxone (regarding number of sensors supported on a bus) it could be useful to have 4 values presented on a single sensor, so reading the extra voltage could be useful, but how many bytes on the wire does it 'cost' to get the single, extra 10 bit voltage value?

Looking at the above link, seems like 270-ish bytes (both TX/RX) are required to configure the A/D bit, initiate voltage conversion and read results (well - if I've understood it correctly, please tell me if that's not the case).

If that is correct, using a DS2438 sounds a terribly inefficient way to get just one extra 10 bit value and one would likely be much better off emulating multiple DS1820 (or similar) devices.

raintonr commented 3 years ago

In case I didn't make it clear, PR #97 seems to fix the DS2438 problem with Loxone here.

Found this through trial and error seeing which of the changes in the modified version I linked above made things work. Just looks like it was because sometimes calcCRC was skipped & guess Loxone may be causing this skip, or actually checking CRCs where other masters don't?

raintonr commented 3 years ago

3fc416dece2b5c1d18fb7d6adb46abc45840189b enables emulation of VDD/VAD voltage reading which Loxone users should find useful.