DIY Feuchtigkeitssensor übermittelt keine Daten

Entwicklung und Bau von Hardware aller Art, die im HM-Umfeld eingesetzt werden kann

Moderator: Co-Administratoren

Antworten
RG1004
Beiträge: 30
Registriert: 02.01.2021, 14:51
System: CCU
Hat sich bedankt: 2 Mal

DIY Feuchtigkeitssensor übermittelt keine Daten

Beitrag von RG1004 » 31.12.2021, 13:54

Ich habe mir den Bausatz bei Smartkram gekauft und zusammengebaut, die Software installiert und den Sensor angelernt.
Nach ein paar Versuchen hat das auch geklappt. Leider übermittelt der Sensor keine Daten:
Screenshot WebUI.png
Ich kann den Sensor auch problemlos erreichen und habe auch schon den Sendeintervall auf 1 min umgestellt (im Bild wieder 30min).
Das kommt im Serial Monitor des Arduino auch so an, sollte also klappen:
Parameter Fühler.png
Was mir aufgefallen ist, ist dass das Funksignal zwischen -210dBm und -37dBm wechselt obwohl der Testaufbau ca. 5m von der Raspi Antenne weg ist.

Verwendetes System:
- Raspberrymatic (4B), Firmware 3.61.5 mit RPI-RF-MOD Funkkarte
- JP HB Device installiert, V 5.8
- Library für den Fühler:

Code: Alles auswählen

//- -----------------------------------------------------------------------------------------------------------------------
// AskSin++
// 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
// 2018-04-16 jp112sdl Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
//- -----------------------------------------------------------------------------------------------------------------------

//Sensor:
//https://www.dfrobot.com/wiki/index.php/Capacitive_Soil_Moisture_Sensor_SKU:SEN0193

// define this to read the device id, serial and device type from bootloader section
// #define USE_OTA_BOOTLOADER

#define EI_NOTEXTERNAL
#include <EnableInterrupt.h>
#include <AskSinPP.h>
#include <LowPower.h>

#include <Register.h>
#include <MultiChannelDevice.h>

// Arduino Pro mini 8 Mhz
// Arduino pin for the config button
#define CONFIG_BUTTON_PIN 8
#define ISR_PIN           9

// number of available peers per channel
#define PEERS_PER_CHANNEL 6

// all library classes are placed in the namespace 'as'
using namespace as;

//Korrekturfaktor der Clock-Ungenauigkeit, wenn keine RTC verwendet wird
#define SYSCLOCK_FACTOR    0.88

#define LED_PIN            4
#define BATT_EN_PIN        6
#define BATT_SENS_PIN      A3

volatile bool isrDetected = false;

//SENSOR_EN_PIN und SENSOR_PIN sind immer paarweise und kommagetrennt hinzuzufügen:

byte SENSOR_EN_PINS[]      {5, 5, 5, 5, 7 , 7, 7}; //VCC Pin des Sensors
byte SENSOR_PINS[]         {14, 15, 16, 18, 19, 20, 21}; //AOut Pin des Sensors

#define sendISR(pin) class sendISRHandler { \
    public: \
      static void isr () { isrDetected = true; } \
  }; \
  pinMode(pin, INPUT_PULLUP); \
  if( digitalPinToInterrupt(pin) == NOT_AN_INTERRUPT ) \
    enableInterrupt(pin,sendISRHandler::isr,RISING); \
  else \
    attachInterrupt(digitalPinToInterrupt(pin),sendISRHandler::isr,RISING);

// define all device properties
const struct DeviceInfo PROGMEM devinfo = {
  {0xF3, 0x11, 0x03},          // Device ID
  "JPCAPM0003",                // Device Serial
  {0xF3, 0x11},                // Device Model
  0x11,                        // Firmware Version
  as::DeviceType::THSensor,    // Device Type
  {0x01, 0x01}                 // Info Bytes
};

/**
   Configure the used hardware
*/
typedef AvrSPI<10, 11, 12, 13> SPIType;
typedef Radio<SPIType, 2> RadioType;
typedef StatusLed<LED_PIN> LedType;
typedef AskSin<LedType, BatterySensorUni<BATT_SENS_PIN, BATT_EN_PIN, 0>, RadioType> BaseHal;
class Hal : public BaseHal {
  public:
    void init (const HMID& id) {
      BaseHal::init(id);
      battery.init(seconds2ticks(60UL * 60) * SYSCLOCK_FACTOR, sysclock); //battery measure once an hour
      battery.low(22);
      battery.critical(19);
    }

    bool runready () {
      return sysclock.runready() || BaseHal::runready();
    }
} hal;


DEFREGISTER(UReg0, MASTERID_REGS, DREG_BURSTRX, DREG_LOWBATLIMIT, 0x21, 0x22)
class UList0 : public RegList0<UReg0> {
  public:
    UList0 (uint16_t addr) : RegList0<UReg0>(addr) {}

    bool Sendeintervall (uint16_t value) const {
      return this->writeRegister(0x21, (value >> 8) & 0xff) && this->writeRegister(0x22, value & 0xff);
    }
    uint16_t Sendeintervall () const {
      return (this->readRegister(0x21, 0) << 8) + this->readRegister(0x22, 0);
    }

    void defaults () {
      clear();
      burstRx(false);
      lowBatLimit(22);
      Sendeintervall(30);
    }
};

DEFREGISTER(UReg1, 0x23, 0x24, 0x25, 0x26)
class UList1 : public RegList1<UReg1> {
  public:
    UList1 (uint16_t addr) : RegList1<UReg1>(addr) {}
    bool HIGHValue (uint16_t value) const {
      return this->writeRegister(0x23, (value >> 8) & 0xff) && this->writeRegister(0x24, value & 0xff);
    }
    uint16_t HIGHValue () const {
      return (this->readRegister(0x23, 0) << 8) + this->readRegister(0x24, 0);
    }

    bool LOWValue (uint16_t value) const {
      return this->writeRegister(0x25, (value >> 8) & 0xff) && this->writeRegister(0x26, value & 0xff);
    }
    uint16_t LOWValue () const {
      return (this->readRegister(0x25, 0) << 8) + this->readRegister(0x26, 0);
    }

    void defaults () {
      clear();
      HIGHValue(830);
      LOWValue(420);
    }
};

class WeatherEventMsg : public Message {
  public:
    void init(uint8_t msgcnt, uint8_t channel, uint8_t val, bool batlow, uint8_t volt) {

      Message::init(0x0e, msgcnt, 0x70, BCAST , batlow ? 0x80 : 0x00, 0x00);
      pload[0] = val     & 0xff;
      pload[1] = channel & 0xff;
      pload[2] = volt    & 0xff;
    }
};

class WeatherChannel : public Channel<Hal, UList1, EmptyList, List4, PEERS_PER_CHANNEL, UList0>, public Alarm {
    WeatherEventMsg msg;
    uint16_t        millis;
    uint8_t         humidity;

  public:
    WeatherChannel () : Channel(), Alarm(0), millis(0) {}
    virtual ~WeatherChannel () {}

    void measure() {
      digitalWrite(SENSOR_EN_PINS[(number() - 1)], HIGH);
      _delay_ms(500);
      uint16_t sens_val = 0;
      for (uint8_t i = 0; i < 10; i++) {
        sens_val += analogRead(SENSOR_PINS[(number() - 1)]);
        _delay_ms(10);
      }
      sens_val = sens_val / 10;
      digitalWrite(SENSOR_EN_PINS[(number() - 1)], LOW);
      DPRINT(F("+Sensor    (#")); DDEC(number()); DPRINT(F(") V: ")); DDECLN(sens_val);
      uint16_t range = this->getList1().HIGHValue() - this->getList1().LOWValue();
      uint32_t base = sens_val - this->getList1().LOWValue();
      uint8_t pct_inv = (100 * base) / range;
      humidity = (pct_inv > 100) ? 0 : 100 - pct_inv;
      DPRINT(F("+Humidity  (#")); DDEC(number()); DPRINT(F(") %: ")); DDECLN(humidity);
    }

    void irq () {
      sysclock.cancel(*this);
      processMessage();
    }

    virtual void trigger (__attribute__ ((unused)) AlarmClock& clock) {
      processMessage();
    }

    void processMessage() {
      measure();
      tick = delay();
      DPRINT(F("+Battery   (#")); DDEC(number()); DPRINT(F(") V: ")); DDECLN(device().battery().current());
      msg.init(device().nextcount(), number(), humidity, device().battery().low(), device().battery().current());
      device().sendPeerEvent(msg, *this);
      sysclock.add(*this);
    }

    uint32_t delay () {
      uint16_t _txMindelay = 30;
      _txMindelay = device().getList0().Sendeintervall();
      if (_txMindelay == 0) _txMindelay = 30;
      return seconds2ticks(_txMindelay * 60 * SYSCLOCK_FACTOR);
    }

    void configChanged() {
      DPRINTLN(F("Config changed List1"));
      DPRINT(F("*HIGHValue (#")); DDEC(number()); DPRINT(F("): ")); DDECLN(this->getList1().HIGHValue());
      DPRINT(F("*LOWValue  (#")); DDEC(number()); DPRINT(F("): ")); DDECLN(this->getList1().LOWValue());
    }

    void setup(Device<Hal, UList0>* dev, uint8_t number, uint16_t addr) {
      Channel::setup(dev, number, addr);
      pinMode(SENSOR_PINS[ number - 1 ], INPUT);
      pinMode(SENSOR_EN_PINS[ number - 1 ], OUTPUT);
      sysclock.add(*this);
    }

    uint8_t status () const {
      return 0;
    }

    uint8_t flags () const {
      return 0;
    }
};

class UType : public MultiChannelDevice<Hal, WeatherChannel, sizeof(SENSOR_PINS), UList0> {
  public:
    typedef MultiChannelDevice<Hal, WeatherChannel, sizeof(SENSOR_PINS), UList0> TSDevice;
    UType(const DeviceInfo& info, uint16_t addr) : TSDevice(info, addr) {}
    virtual ~UType () {}

    virtual void configChanged () {
      TSDevice::configChanged();
      DPRINT(F("*LOW BAT Limit: "));
      DDECLN(this->getList0().lowBatLimit());
      DPRINT(F("*Wake-On-Radio: "));
      DDECLN(this->getList0().burstRx());
      this->battery().low(this->getList0().lowBatLimit());
      DPRINT(F("*Sendeintervall: ")); DDECLN(this->getList0().Sendeintervall());
    }
};

UType sdev(devinfo, 0x20);
ConfigButton<UType> cfgBtn(sdev);

void setup () {
  DINIT(57600, ASKSIN_PLUS_PLUS_IDENTIFIER);
  if (sizeof(SENSOR_PINS) != sizeof(SENSOR_EN_PINS)) {
    DPRINTLN(F("!!! ERROR: Anzahl SENSOR_PINS entspricht nicht der Anzahl SENSOR_EN_PINS"));
  } else {
    sdev.init(hal);
    DDEVINFO(sdev);
    buttonISR(cfgBtn, CONFIG_BUTTON_PIN);
#ifdef ISR_PIN
    sendISR(ISR_PIN);
#endif
    sdev.initDone();
  }
}

void loop() {
  bool worked = hal.runready();
  bool poll = sdev.pollRadio();

  if ( worked == false && poll == false ) {
    if (isrDetected) {
      DPRINTLN(F("manual button pressed"));
      for (uint8_t i = 1; i <= sizeof(SENSOR_PINS); i++) {
        sdev.channel(i).irq();
      }
      isrDetected = false;
    }

    if ( hal.battery.critical() ) {
      hal.activity.sleepForever(hal);
    }
    hal.activity.savePower<Sleep<>>(hal);
  }
}
Ich hab auch eine andere Library probiert (die aus 2019). Da lässt sich der Fühler aber nicht anlernen.

Hat jemand ähnliche Erfahrungen oder eine Idee.

Danke

HMSteve
Beiträge: 342
Registriert: 20.08.2019, 06:23
Hat sich bedankt: 8 Mal
Danksagung erhalten: 57 Mal

Re: DIY Feuchtigkeitssensor übermittelt keine Daten

Beitrag von HMSteve » 31.12.2021, 15:30

Bevor wir lange rätseln: Sendefrequenz kalibriert, z.B. mit Frequenztest? -210dBm ist für praktische Belange kein Signal.

Viele Grüße,
Stephan

RG1004
Beiträge: 30
Registriert: 02.01.2021, 14:51
System: CCU
Hat sich bedankt: 2 Mal

Re: DIY Feuchtigkeitssensor übermittelt keine Daten

Beitrag von RG1004 » 01.01.2022, 13:12

Ja.
Habe den Frequenztest mehrmals laufen lassen um zu prüfen ob sich immer stabil die selbe Frequenz einstellt.
Das ist auch so.
Wie gesagt, wenn ich in der WebUI Einstellungen am Sensor vornehme, also z.B. den Sendeintervall verändere, sehe ich das sofort im seriellen Monitor.
Heute zeigt das Funksignal stabil -60dBm an. Der Fühler liegt in einem anderen Raum und weiter entfernt.
Ich möchte nichts ausschließen aber ich denke die Funkverbindung scheint ok zu sein.

Gruß
Roman

jp112sdl
Beiträge: 10059
Registriert: 20.11.2016, 20:01
Hat sich bedankt: 646 Mal
Danksagung erhalten: 1526 Mal
Kontaktdaten:

Re: DIY Feuchtigkeitssensor übermittelt keine Daten

Beitrag von jp112sdl » 01.01.2022, 13:41

RG1004 hat geschrieben:
31.12.2021, 13:54

Code: Alles auswählen

byte SENSOR_PINS[]         {14, 15, 16, 18, 19, 20, 21}; //AOut Pin des Sensors
Pin 21 geht nicht.
https://github.com/jp112sdl/HB-UNI-Sen- ... /issues/12

Weitere Fragen könnte dir evtl. Smartkram noch beantworten ^^

VG,
Jérôme ☕️

---
Support for my Homebrew-Devices: Download JP-HB-Devices Addon

RG1004
Beiträge: 30
Registriert: 02.01.2021, 14:51
System: CCU
Hat sich bedankt: 2 Mal

Re: DIY Feuchtigkeitssensor übermittelt keine Daten

Beitrag von RG1004 » 02.01.2022, 13:33

Hallo Jérôme,

also ich bin jetzt einen Schritt weiter. Der Sensor übermittelt Daten.
Die Herausnahme des Pin 21 hat aber in Bezug auf die Datenübermittlung nichts geändert. Ich habe dann Folgendes gemacht:

1.) Verwendung des neueren Sketch aus 2019:

Code: Alles auswählen

//- -----------------------------------------------------------------------------------------------------------------------
// AskSin++
// 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
// 2019-05-03 jp112sdl Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
// 2019-05-04 stan23 Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
//- -----------------------------------------------------------------------------------------------------------------------
// ci-test=yes board=328p aes=no

//Sensor:
//https://www.dfrobot.com/wiki/index.php/Capacitive_Soil_Moisture_Sensor_SKU:SEN0193

// define this to read the device id, serial and device type from bootloader section
// #define USE_OTA_BOOTLOADER

#define NO_DS18B20 //use model without temperature sensor

#define EI_NOTEXTERNAL
#include <EnableInterrupt.h>
#define SENSOR_ONLY

// Arduino Pro mini 8 Mhz
// Arduino pin for the config button
#define CONFIG_BUTTON_PIN      8
#define LED_PIN                4
#define BATT_EN_PIN            5
#define BATT_SENS_PIN          14  // A0

#define CC1101_GDO0_PIN        2
#define CC1101_CS_PIN          10
#define CC1101_MOSI_PIN        11
#define CC1101_MISO_PIN        12
#define CC1101_SCK_PIN         13
const uint8_t SENSOR_PINS[]    {15, 16, 17, 18, 19, 20}; //AOut Pins der Sensoren (hier A1, A2 und A3)
//bei Verwendung von > 3 Sensoren sollten die Vcc der Sensoren auf 2 Enable Pins verteilt werden (max. Last pro AVR-Pin beachten!)
const uint8_t SENSOR_EN_PINS[] {5, 7}; //VCC Pin des Sensors war "6"

#define DS18B20_PIN            3


#define DEVICE_CHANNEL_COUNT sizeof(SENSOR_PINS)
#include <AskSinPP.h>
#include <LowPower.h>

#include <Register.h>
#include <MultiChannelDevice.h>

#ifndef NO_DS18B20
#include <OneWire.h>
#include <sensors/Ds18b20.h>
OneWire oneWire(DS18B20_PIN);
#endif

// number of available peers per channel
#define PEERS_PER_CHANNEL 4

// all library classes are placed in the namespace 'as'
using namespace as;

//Korrekturfaktor der Clock-Ungenauigkeit, wenn keine RTC verwendet wird
#define SYSCLOCK_FACTOR    0.88

#ifdef NO_DS18B20
#define DEVICE_MODEL  0x11
#else
#define DEVICE_MODEL  0x12
#endif

// define all device properties
const struct DeviceInfo PROGMEM devinfo = {
  {0xF3, DEVICE_MODEL, 0x00},  // Device ID
  "JPCAPM0000",                // Device Serial
  {0xF3, DEVICE_MODEL},        // Device Model
  0x10,                        // Firmware Version
  as::DeviceType::THSensor,    // Device Type
  {0x01, 0x01}                 // Info Bytes
};

/**
   Configure the used hardware
*/
typedef AvrSPI<CC1101_CS_PIN, CC1101_MOSI_PIN, CC1101_MISO_PIN, CC1101_SCK_PIN> SPIType;
typedef Radio<SPIType, CC1101_GDO0_PIN> RadioType;
typedef StatusLed<LED_PIN> LedType;
typedef AskSin<LedType, BatterySensorUni<BATT_SENS_PIN, BATT_EN_PIN, 0>, RadioType> BaseHal;
class Hal : public BaseHal {
  public:
    void init (const HMID& id) {
      BaseHal::init(id);
      battery.init(seconds2ticks(60UL * 60) * SYSCLOCK_FACTOR, sysclock); //battery measure once an hour
      battery.low(22);
      battery.critical(19);
    }

    bool runready () {
      return sysclock.runready() || BaseHal::runready();
    }
} hal;


DEFREGISTER(UReg0, MASTERID_REGS, DREG_LOWBATLIMIT, 0x21, 0x22)
class UList0 : public RegList0<UReg0> {
  public:
    UList0 (uint16_t addr) : RegList0<UReg0>(addr) {}

    bool Sendeintervall (uint16_t value) const {
      return this->writeRegister(0x21, (value >> 8) & 0xff) && this->writeRegister(0x22, value & 0xff);
    }
    uint16_t Sendeintervall () const {
      return (this->readRegister(0x21, 0) << 8) + this->readRegister(0x22, 0);
    }

    void defaults () {
      clear();
      lowBatLimit(22);
      Sendeintervall(30);
    }
};

DEFREGISTER(UReg1, 0x01, 0x02, 0x03, 0x04, 0x23, 0x24, 0x25, 0x26)
class UList1 : public RegList1<UReg1> {
  public:
    UList1 (uint16_t addr) : RegList1<UReg1>(addr) {}
    bool HIGHValue (uint16_t value) const {
      return this->writeRegister(0x23, (value >> 8) & 0xff) && this->writeRegister(0x24, value & 0xff);
    }
    uint16_t HIGHValue () const {
      return (this->readRegister(0x23, 0) << 8) + this->readRegister(0x24, 0);
    }

    bool LOWValue (uint16_t value) const {
      return this->writeRegister(0x25, (value >> 8) & 0xff) && this->writeRegister(0x26, value & 0xff);
    }
    uint16_t LOWValue () const {
      return (this->readRegister(0x25, 0) << 8) + this->readRegister(0x26, 0);
    }

#ifndef NO_DS18B20
    bool Offset (int32_t value) const {
      return
          this->writeRegister(0x01, (value >> 24) & 0xff) &&
          this->writeRegister(0x02, (value >> 16) & 0xff) &&
          this->writeRegister(0x03, (value >> 8)  & 0xff) &&
          this->writeRegister(0x04, (value)       & 0xff)
          ;
    }

    int32_t Offset () const {
      return
          ((int32_t)(this->readRegister(0x01, 0)) << 24) +
          ((int32_t)(this->readRegister(0x02, 0)) << 16) +
          ((int32_t)(this->readRegister(0x03, 0)) << 8 ) +
          ((int32_t)(this->readRegister(0x04, 0))      )
          ;
    }
#endif

    void defaults () {
      clear();
      HIGHValue(830);
      LOWValue(420);
#ifndef NO_DS18B20
      Offset(0);
#endif
    }
};

class WeatherEventMsg : public Message {
  public:
  void init(uint8_t msgcnt, uint8_t *h, bool batlow, uint8_t volt, __attribute__ ((unused))  int16_t temperature, __attribute__ ((unused))  int8_t offset) {

#ifndef NO_DS18B20
    int16_t t = temperature + offset;
    DPRINT(F("+Temp         C : ")); DDECLN(t);
#endif
    DPRINT(F("+Battery      V : ")); DDECLN(volt);
#ifdef NO_DS18B20
#define PAYLOAD_OFFSET 0
#else
#define PAYLOAD_OFFSET 2
#endif

    Message::init(0xc + PAYLOAD_OFFSET + (DEVICE_CHANNEL_COUNT * 2), msgcnt, 0x53, (msgcnt % 20 == 1) ? (BIDI | WKMEUP) : BCAST, batlow ? 0x80 : 0x00, 0x41);

#ifndef NO_DS18B20
    pload[0] = (t >> 8) & 0xff;
    pload[1] = (t)      & 0xff;
#endif

    pload[PAYLOAD_OFFSET] = (volt)   & 0xff;
    for (uint8_t s = 0; s < DEVICE_CHANNEL_COUNT; s++) {
      DPRINT(F("+Humidity (#")); DDEC(s + 1); DPRINT(F(") %: ")); DDECLN(h[s]);
      pload[1+PAYLOAD_OFFSET+(s * 2)] = 0x42 + s;
      pload[2+PAYLOAD_OFFSET+(s * 2)] = h[s] & 0xff;
    }
  }
  void init(uint8_t msgcnt, uint8_t *h, bool batlow, uint8_t volt) {
    init(msgcnt, h, batlow, volt, 0, 0);
  }
};

class WeatherChannel : public Channel<Hal, UList1, EmptyList, List4, PEERS_PER_CHANNEL, UList0> {
  public:
    WeatherChannel () : Channel() {}
    virtual ~WeatherChannel () {}

    void configChanged() {
      DPRINT(F("Config changed List1 (CH "));DDEC(number());DPRINTLN(F(")"));
#ifndef NO_DS18B20
      if (number() == 1) { DPRINT(F("*Offset    : ")); DDECLN(this->getList1().Offset()); }
#endif
      if (number() > 1)  { DPRINT(F("*HIGHValue : ")); DDECLN(this->getList1().HIGHValue()); }
      if (number() > 1)  { DPRINT(F("*LOWValue  : ")); DDECLN(this->getList1().LOWValue()); }
    }

    uint8_t status () const {
      return 0;
    }

    uint8_t flags () const {
      return 0;
    }
};

class UType : public MultiChannelDevice<Hal, WeatherChannel, DEVICE_CHANNEL_COUNT + 1, UList0> {
public:
#ifndef NO_DS18B20
  Ds18b20      sensor[1];
#endif
  class SensorArray : public Alarm {
       UType& dev;

       public:
         uint8_t       humidity[DEVICE_CHANNEL_COUNT];
         SensorArray (UType& d) : Alarm(0), dev(d) {}
         virtual ~SensorArray () {}

         void measure() {
           //enable all moisture sensors
           for (uint8_t s = 0; s < sizeof(SENSOR_EN_PINS); s++) {
             digitalWrite(SENSOR_EN_PINS[s], HIGH);
             _delay_ms(5);
           }

           //wait a moment to settle
           _delay_ms(500);
           //now measure all sensors
           for (uint8_t s = 0; s < DEVICE_CHANNEL_COUNT; s++) {
             uint16_t sens_val = 0;

             //measure 8 times and calculate average
             for (uint8_t i = 0; i < 8; i++) {
               sens_val += analogRead(SENSOR_PINS[s]);
               _delay_ms(10);
             }
             sens_val /= 8;

             DPRINT(F("+Analog     (#")); DDEC(s + 1); DPRINT(F("): ")); DDEC(sens_val);
             uint16_t upper_limit = dev.channel(s + 2).getList1().HIGHValue();
             uint16_t lower_limit = dev.channel(s + 2).getList1().LOWValue();
             if (sens_val > upper_limit) {
               humidity[s] = 0;
               DPRINTLN(F(" higher than limit!"));
             }
             else if (sens_val < lower_limit) {
               humidity[s] = 100;
               DPRINTLN(F(" lower than limit!"));
             }
             else {
               uint16_t range = upper_limit - lower_limit;
               uint32_t base = sens_val - lower_limit;
               uint8_t pct_inv = (base * 100) / range;
               humidity[s] = 100 - pct_inv;
               DPRINTLN("");
             }

             //humidity[s] = random(0,100);

           }
           //disable all moisture sensors
           for (uint8_t s = 0; s < sizeof(SENSOR_EN_PINS); s++)
             digitalWrite(SENSOR_EN_PINS[s], LOW);

#ifndef NO_DS18B20
           Ds18b20::measure(dev.sensor, 1);
#endif
         }

         virtual void trigger (__attribute__ ((unused)) AlarmClock& clock) {
           measure();
           tick = delay();
           WeatherEventMsg& msg = (WeatherEventMsg&)dev.message();
#ifndef NO_DS18B20
           msg.init(dev.nextcount(), humidity, dev.battery().low(), dev.battery().current(), dev.sensor[0].temperature(), dev.channel(1).getList1().Offset());
#else
           msg.init(dev.nextcount(), humidity, dev.battery().low(), dev.battery().current());
#endif
           dev.send(msg, dev.getMasterID());
           sysclock.add(*this);
         }

         uint32_t delay () {
           //Sendeintervall festlegen
           uint16_t _txDelay = max(dev.getList0().Sendeintervall(), 1);
           return seconds2ticks(_txDelay * 60 * SYSCLOCK_FACTOR);
         }

      } sensarray;


    typedef MultiChannelDevice<Hal, WeatherChannel, DEVICE_CHANNEL_COUNT + 1, UList0> TSDevice;
    UType(const DeviceInfo& info, uint16_t addr) : TSDevice(info, addr), sensarray(*this) {}
    virtual ~UType () {}

    void init (Hal& hal) {
      TSDevice::init(hal);
      for (uint8_t s = 0; s < DEVICE_CHANNEL_COUNT; s++)
        pinMode(SENSOR_PINS[ s ], INPUT);

      for (uint8_t s = 0; s < sizeof(SENSOR_EN_PINS); s++)
      pinMode(SENSOR_EN_PINS[s], OUTPUT);

#ifndef NO_DS18B20
      uint8_t sensorcount = Ds18b20::init(oneWire, sensor, 1);
      DPRINT(F("DS18B20 Sensor "));DPRINTLN((sensorcount > 0) ? F("OK"):F("ERROR"));
#endif
      sensarray.set(seconds2ticks(5));
      sysclock.add(sensarray);
    }

    virtual void configChanged () {
      TSDevice::configChanged();
      DPRINT(F("*LOW BAT Limit: "));
      DDECLN(this->getList0().lowBatLimit());
      this->battery().low(this->getList0().lowBatLimit());
      DPRINT(F("*Sendeintervall: ")); DDECLN(this->getList0().Sendeintervall());

    }
};

UType sdev(devinfo, 0x20);
ConfigButton<UType> cfgBtn(sdev);

void setup () {
  DINIT(57600, ASKSIN_PLUS_PLUS_IDENTIFIER);
  sdev.init(hal);
  DDEVINFO(sdev);
  buttonISR(cfgBtn, CONFIG_BUTTON_PIN);
  sdev.initDone();
}

void loop() {
  bool worked = hal.runready();
  bool poll = sdev.pollRadio();

  if ( worked == false && poll == false ) {
    if ( hal.battery.critical() ) {
      DPRINT(F("Battery critical! "));DDECLN(hal.battery.current());
      Serial.flush();
      hal.activity.sleepForever(hal);
    }
    hal.activity.savePower<Sleep<>>(hal);
  }
}
Dabei habe ich folgende Änderungen vorgenommen:
1A.) Temperatursensor "entfernt":

Code: Alles auswählen

#define NO_DS18B20 //use model without temperature sensor
1B.) Die Sensorenpins zugeordnet:

Code: Alles auswählen

const uint8_t SENSOR_PINS[]    {15, 16, 17, 18, 19, 20}; //AOut Pins der Sensoren (hier A1, A2 und A3)
//bei Verwendung von > 3 Sensoren sollten die Vcc der Sensoren auf 2 Enable Pins verteilt werden (max. Last pro AVR-Pin beachten!)
const uint8_t SENSOR_EN_PINS[] {5, 7}; //VCC Pin des Sensors war "6"
Das Ergebnis in der WebUI ist jetzt Folgendes:
2022-01-02 Screenshot WebUi.png
Das Ergebnis im Serial Monitor dazu ist:

Code: Alles auswählen

13:28:35.459 -> +Analog     (#1): 0
13:28:35.506 -> +Analog     (#2): 9
13:28:35.600 -> +Analog     (#3): 1006
13:28:35.693 -> +Analog     (#4): 0
13:28:35.787 -> +Analog     (#5): 564
13:28:35.880 -> +Analog     (#6): 486
13:28:35.880 -> +Battery      V : 42
13:28:35.880 -> +Humidity (#1) %: 100
13:28:35.880 -> +Humidity (#2) %: 100
13:28:35.880 -> +Humidity (#3) %: 2
13:28:35.880 -> +Humidity (#4) %: 100
13:28:35.880 -> +Humidity (#5) %: 45
13:28:35.880 -> +Humidity (#6) %: 53
13:28:35.927 -> <- 18 28 84 53 F31100 BA4BC3 00 41 2A 42 64 43 64 44 02 45 64 46 2D 47 
Ich muss also jetzt die Sensoren noch kalibrieren.

Leider geht jetzt aber der 7. Sensor nicht mehr da ich den Pin "21" entfernt habe.
Ich bin mir auch nicht sicher ob ich die Pin Definition richtig gemacht habe.
Meine Fragen wären daher:
1.) wie aktiviere ich den 7. Sensor wenn ich den Pin 21 nicht verwenden darf?
2.) wie setze ich die "SENSOR_EN_PINS" richtig?

Jedenfalls danke für die Hilfe bis daher.

LG Roman

jp112sdl
Beiträge: 10059
Registriert: 20.11.2016, 20:01
Hat sich bedankt: 646 Mal
Danksagung erhalten: 1526 Mal
Kontaktdaten:

Re: DIY Feuchtigkeitssensor übermittelt keine Daten

Beitrag von jp112sdl » 02.01.2022, 14:49

RG1004 hat geschrieben:
02.01.2022, 13:33
1.) wie aktiviere ich den 7. Sensor wenn ich den Pin 21 nicht verwenden darf?
Glaub gar nicht. Zumindest nicht mit dem 328P. Oder mit einem externen ADC.
RG1004 hat geschrieben:
02.01.2022, 13:33
2.) wie setze ich die "SENSOR_EN_PINS" richtig?
Ich hab keine Ahnung wie die Sensoren bei der Smartkram PCB verdrahtet sind.

VG,
Jérôme ☕️

---
Support for my Homebrew-Devices: Download JP-HB-Devices Addon

Antworten

Zurück zu „Hardwareentwicklung und Selbstbau von Aktoren und Sensoren“