DIY Feuchtigkeitssensor übermittelt keine Daten
Verfasst: 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: 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: 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:
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
Nach ein paar Versuchen hat das auch geklappt. Leider übermittelt der Sensor keine Daten: 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: 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);
}
}
Hat jemand ähnliche Erfahrungen oder eine Idee.
Danke