Neuigkeiten:

Am Sonntag den 8.12.2024 kann es ab ca. 8:00 Uhr zu kurzzeitigen Einschränkungen / Ausfällen bei den Diensten des FHEM Vereines kommen.
Die Server müssen mal gewartet und dabei neu gestartet werden ;)

Hauptmenü

MySensors Node mit Si7021, BH1750 und Pir

Begonnen von beSmart, 04 Mai 2019, 15:47:25

Vorheriges Thema - Nächstes Thema

beSmart

Hallo Forum.

Wie in diesem Thread beschrieben, versuche ich einen Multi-Node mit Luftfeuchte, Temperatur, Lux und Pir zu bauen.
https://forum.fhem.de/index.php/topic,99112.0.html

Da nicht ganz klar ist, ob der Speicher eines Pro Mini für den Sketch mit BME280 ausreicht und meine Programmierkenntnisse mehr oder weniger aus copy und paste bestehen, habe ich versucht den BME durch einen Si7021 zu ersetzen. Dieser Versuch war zu 2/3 erfolgreich und der Sketch passt locker auf den Pro Mini. Das letzte drittel allerdings "der BH1750" beschäftigt mich jetzt schon seit Wochen, ohne das ich vorankomme.
Der BH1750 liefert keine Daten.

Die Verkabelung und den Sensor kann ich als Fehlerquelle ausschließen, da der Sketch für den BH1750 von Mysensors funktioniert. Es muss also an meinem copy und paste Künsten liegen.
Vielleicht mag ja jemand drüber schauen und mir einen Tipp geben, welchen Teil ich mir genauer anschauen sollte.


// Enable debug prints
#define MY_DEBUG

// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
//#define MY_RS485

#include <SPI.h>
#include <BH1750.h>
#include <Wire.h>
#include <MySensors.h> 
#include <SI7021.h>


#define CHILD_ID_HUM  0
#define CHILD_ID_TEMP 1
static bool metric = true;
#define CHILD_ID_LIGHT 2
// Sleep time between reads (in milliseconds)BH1750
//unsigned long SLEEP_TIME = 30000;
BH1750 lightSensor;
uint32_t SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
// The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
#define DIGITAL_INPUT_SENSOR 3   
#define CHILD_ID_Motion 4   // Id of the sensor child

// Sleep time between sensor updates (in milliseconds)SI7012
static const uint64_t UPDATE_INTERVAL = 60000;
static SI7021 sensor;
// V_LIGHT_LEVEL should only be used for uncalibrated light level 0-100%.
// If your controller supports the new V_LEVEL variable, use this instead for
// transmitting LUX light level.
//MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL CHILD_ID, V_TRIPPED);
MyMessage msg(CHILD_ID_LIGHT, V_LEVEL); 
MyMessage msgHum( CHILD_ID_HUM,  V_HUM );
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
// Initialize motion message
MyMessage msgMotion(CHILD_ID_Motion, V_TRIPPED);

uint16_t lastlux;

void presentation() 
{
  // Send the sketch version information to the gateway and Controller
    sendSketchInfo("TestSensor", "1.0");

    // Register all sensors to gw (they will be created as child devices)
   present(CHILD_ID_Motion, S_MOTION);
  // Present sensors as children to gateway
  present(CHILD_ID_HUM, S_HUM,   "Humidity");
  present(CHILD_ID_TEMP, S_TEMP, "Temperature");
// Register all sensors to gateway (they will be created as child devices)
  present(CHILD_ID_LIGHT, S_LIGHT_LEVEL, "Lux");

  metric = getControllerConfig().isMetric;
}

void setup()
{
  while (not sensor.begin())
lightSensor.begin();
pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
  {
    Serial.println(F("Sensor not detected!"));
    delay(5000);
  }
}


void loop()     

// Read digital motion value
    bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;

    Serial.println(tripped);
    send(msg.set(tripped?"1":"0"));  // Send tripped value to gw

    // Sleep until interrupt comes in on motion sensor. Send update every two minute.
    sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
  // Read temperature & humidity from sensor.
  const float temperature = float( metric ? sensor.getCelsiusHundredths() : sensor.getFahrenheitHundredths() ) / 100.0;
  const float humidity    = float( sensor.getHumidityBasisPoints() ) / 100.0;

#ifdef MY_DEBUG
  Serial.print(F("Temp "));
  Serial.print(temperature);
  Serial.print(metric ? 'C' : 'F');
  Serial.print(F("\tHum "));
  Serial.println(humidity);
#endif
uint16_t lux = lightSensor.readLightLevel();// Get Lux value
  Serial.println(lux);
  if (lux != lastlux){
      send(msg.set(lux));
      lastlux = lux;
  }

  send(msgTemp.set(temperature, 2));
  send(msgHum.set(humidity, 2));



  // Sleep until next update to save energy
  sleep(UPDATE_INTERVAL);
}


Dank und Gruß


Dirk

Beta-User

Hmm, du solltest evtl. mal etwas mehr an debug-info an serial geben, damit du siehst, was alles erfolgreich abgearbeitet wird.

Hier wäre nett, wenn du mitteilst, ob überhaupt die Presentation abgearbeitet wird, oder ob er vorher schon hängt.

Hier finde ich das mit den 2 sleeps ungeschickt, das sollte nur eine (am Ende der loop) sein, da aber dann die mit beiden Bedingungen, die andere TIMER-Dauer kann ganz raus.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

beSmart

Hallo und vielen Dank für deine Antwort.

Werde versuchen das so umzubauen. Aber erst zum Wochenende..... irgendwie läuft es gerade nicht....
Ich melde mich dann wieder.

Dank und Gruß


Dirk

beSmart

Hallo Beta-User.

Jetzt funktioniert der Sensor! Ich habe alles gelöscht und bin noch mal ganz von vorn angefangen. Das der BH1750 keine Daten geliefert hat,  lag wahrscheinlich an einer defekten Bibliothek.
Der Sensor sendet alle 10Min. die Messwerte an der Server. Was mir nicht so gut gefällt ist, das die Messwerte auch gesendet werden, wenn der PIR ausgelöst wird. Aber damit kann ich leben.

Nochmal vielen Dank für deine Tipps! Ich habe viel dazu gelernt.

Hier noch mal der funktionierende Programmcode für alle die ihn gebrauchen können: Dieser stammt nicht von mir, sondern wurde aus den Beispielen von MySensors zusammen kopiert.


/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - idefix
*
* DESCRIPTION
* Arduino BH1750FVI Light sensor
* communicate using I2C Protocol
* this library enable 2 slave device addresses
* Main address  0x23
* secondary address 0x5C
* connect the sensor as follows :
*
*   VCC  >>> 5V
*   Gnd  >>> Gnd
*   ADDR >>> NC or GND 
*   SCL  >>> A5
*   SDA  >>> A4
*   PIR  >>> D3
* https://www.mysensors.org/build/light-bh1750
*/


// Enable debug prints to serial monitor
#define MY_DEBUG

// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69

#include <MySensors.h> 
#include <BH1750.h>
#include <Wire.h>



uint32_t SLEEP_TIME = 600000; // Sleep time between reports (in milliseconds)
#define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
#define CHILD_ID_Motion 0 
#define CHILD_ID_LIGHT 1
#define CHILD_ID_HUM  2
#define CHILD_ID_TEMP 3

static bool metric = true;



//unsigned long SLEEP_TIME2 = 600000; // Sleep time between reads (in milliseconds)


BH1750 lightSensor;

#include <SI7021.h>
static SI7021 sensor;

// V_LIGHT_LEVEL should only be used for uncalibrated light level 0-100%.
// If your controller supports the new V_LEVEL variable, use this instead for
// transmitting LUX light level.
//MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
//MyMessage msgMotion(CHILD_ID_Motion, V_TRIPPED);
//MyMessage msgLight(CHILD_ID_LIGHT, V_LEVEL); 
uint16_t lastlux;

void setup() 
{
  lightSensor.begin();
   while (not sensor.begin())
   
    Serial.println(F("Sensor not detected!"));
    delay(5000);

    pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
}

void presentation()
{
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo("Multi_Node", "1.0");

  // Register all sensors to gateway (they will be created as child devices)
  present(CHILD_ID_LIGHT, S_LIGHT_LEVEL,    "Light");
   present(CHILD_ID_HUM, S_HUM,    "Humidity");
  present(CHILD_ID_TEMP, S_TEMP,    "Temperature");
   // Register all sensors to gw (they will be created as child devices)
   present(CHILD_ID_Motion, S_MOTION,    "Motion");

  metric = getControllerConfig().isMetric;
}

void loop()
{     
  static MyMessage msgLight(CHILD_ID_LIGHT, V_LEVEL); 
  static MyMessage msgHum( CHILD_ID_HUM,  V_HUM );
  static MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
  static MyMessage msgMotion(CHILD_ID_Motion, V_TRIPPED);
   
  uint16_t lux = lightSensor.readLightLevel();// Get Lux value
  Serial.println(lux);
  if (lux != lastlux) {
      send(msgLight.set(lux));
      lastlux = lux;
 
  const float temperature = float( metric ? sensor.getCelsiusHundredths() : sensor.getFahrenheitHundredths() ) / 100.0;
  const float humidity    = float( sensor.getHumidityBasisPoints() ) / 100.0;

#ifdef MY_DEBUG
  Serial.print(F("Temp "));
  Serial.print(temperature);
  Serial.print(metric ? 'C' : 'F');
  Serial.print(F("\tHum "));
  Serial.println(humidity);
#endif


  send(msgTemp.set(temperature, 2));
  send(msgHum.set(humidity, 2));

  bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;

    Serial.println(tripped);
    send(msgMotion.set(tripped?"1":"0"));  // Send tripped value to gw

    // Sleep until interrupt comes in on motion sensor. Send update every two minute.
   sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
}

  //sleep(SLEEP_TIME2);
}




Dank und Gruß


Dirk

Beta-User

 :)
Danke für die Rückmeldung. Bitte ggf. auch noch ein [gelöst] vor den Thread-Titel?

Um das verbliebene Thema mit der Dauer/Sendung der Meßwerte beim Aufwachen zu lösen: Das geht vermutlich auch. Hab' das zwar noch nicht selbst gemacht, aber einen Ansatz in meiner Linkliste "für irgendwann mal" abgelegt: https://forum.mysensors.org/topic/9595/interrupted-sleep/11 (bzw. auch der Beitrag davor).
Vielleicht hilft dir das weiter?
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files