├── HB-UNI-Sen-CAP-MOIST.ino ├── Images ├── SEN0193-line.png ├── arduino_ide_serialmonitor.png ├── aufbau1.jpg ├── aufbau2.jpg ├── aufbau3.jpg ├── ccu_addon.png ├── ccu_einstellungen.png ├── ccu_geraete.png ├── ccu_status.png ├── wiring2.fzz └── wiring2.png └── README.md /HB-UNI-Sen-CAP-MOIST.ino: -------------------------------------------------------------------------------- 1 | //- ----------------------------------------------------------------------------------------------------------------------- 2 | // AskSin++ 3 | // 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ 4 | // 2019-05-03 jp112sdl Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ 5 | // 2019-05-04 stan23 Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ 6 | //- ----------------------------------------------------------------------------------------------------------------------- 7 | // ci-test=yes board=328p aes=no 8 | 9 | //Sensor: 10 | //https://www.dfrobot.com/wiki/index.php/Capacitive_Soil_Moisture_Sensor_SKU:SEN0193 11 | 12 | // define this to read the device id, serial and device type from bootloader section 13 | // #define USE_OTA_BOOTLOADER 14 | 15 | // #define NO_DS18B20 //use model without temperature sensor 16 | 17 | #define EI_NOTEXTERNAL 18 | #include 19 | #define SENSOR_ONLY 20 | 21 | // Arduino Pro mini 8 Mhz 22 | // Arduino pin for the config button 23 | #define CONFIG_BUTTON_PIN 8 24 | #define LED_PIN 4 25 | #define BATT_EN_PIN 5 26 | #define BATT_SENS_PIN 14 // A0 27 | 28 | #define CC1101_GDO0_PIN 2 29 | #define CC1101_CS_PIN 10 30 | #define CC1101_MOSI_PIN 11 31 | #define CC1101_MISO_PIN 12 32 | #define CC1101_SCK_PIN 13 33 | const uint8_t SENSOR_PINS[] {15, 16, 17}; //AOut Pins der Sensoren (hier A1, A2 und A3) 34 | //bei Verwendung von > 3 Sensoren sollten die Vcc der Sensoren auf 2 Enable Pins verteilt werden (max. Last pro AVR-Pin beachten!) 35 | const uint8_t SENSOR_EN_PINS[] {6}; 36 | 37 | #define DS18B20_PIN 3 38 | 39 | 40 | #define DEVICE_CHANNEL_COUNT sizeof(SENSOR_PINS) 41 | #include 42 | #include 43 | 44 | #include 45 | #include 46 | 47 | #ifndef NO_DS18B20 48 | #include 49 | #include 50 | OneWire oneWire(DS18B20_PIN); 51 | #endif 52 | 53 | // number of available peers per channel 54 | #define PEERS_PER_CHANNEL 4 55 | 56 | // all library classes are placed in the namespace 'as' 57 | using namespace as; 58 | 59 | //Korrekturfaktor der Clock-Ungenauigkeit, wenn keine RTC verwendet wird 60 | #define SYSCLOCK_FACTOR 0.88 61 | 62 | #ifdef NO_DS18B20 63 | #define DEVICE_MODEL 0x11 64 | #else 65 | #define DEVICE_MODEL 0x12 66 | #endif 67 | 68 | // define all device properties 69 | const struct DeviceInfo PROGMEM devinfo = { 70 | {0xF3, DEVICE_MODEL, 0x00}, // Device ID 71 | "JPCAPM0000", // Device Serial 72 | {0xF3, DEVICE_MODEL}, // Device Model 73 | 0x10, // Firmware Version 74 | as::DeviceType::THSensor, // Device Type 75 | {0x01, 0x01} // Info Bytes 76 | }; 77 | 78 | /** 79 | Configure the used hardware 80 | */ 81 | typedef AvrSPI SPIType; 82 | typedef Radio RadioType; 83 | typedef StatusLed LedType; 84 | typedef AskSin, RadioType> BaseHal; 85 | class Hal : public BaseHal { 86 | public: 87 | void init (const HMID& id) { 88 | BaseHal::init(id); 89 | battery.init(seconds2ticks(60UL * 60) * SYSCLOCK_FACTOR, sysclock); //battery measure once an hour 90 | battery.low(22); 91 | battery.critical(19); 92 | } 93 | 94 | bool runready () { 95 | return sysclock.runready() || BaseHal::runready(); 96 | } 97 | } hal; 98 | 99 | 100 | DEFREGISTER(UReg0, MASTERID_REGS, DREG_LOWBATLIMIT, 0x21, 0x22) 101 | class UList0 : public RegList0 { 102 | public: 103 | UList0 (uint16_t addr) : RegList0(addr) {} 104 | 105 | bool Sendeintervall (uint16_t value) const { 106 | return this->writeRegister(0x21, (value >> 8) & 0xff) && this->writeRegister(0x22, value & 0xff); 107 | } 108 | uint16_t Sendeintervall () const { 109 | return (this->readRegister(0x21, 0) << 8) + this->readRegister(0x22, 0); 110 | } 111 | 112 | void defaults () { 113 | clear(); 114 | lowBatLimit(22); 115 | Sendeintervall(30); 116 | } 117 | }; 118 | 119 | DEFREGISTER(UReg1, 0x01, 0x02, 0x03, 0x04, 0x23, 0x24, 0x25, 0x26) 120 | class UList1 : public RegList1 { 121 | public: 122 | UList1 (uint16_t addr) : RegList1(addr) {} 123 | bool HIGHValue (uint16_t value) const { 124 | return this->writeRegister(0x23, (value >> 8) & 0xff) && this->writeRegister(0x24, value & 0xff); 125 | } 126 | uint16_t HIGHValue () const { 127 | return (this->readRegister(0x23, 0) << 8) + this->readRegister(0x24, 0); 128 | } 129 | 130 | bool LOWValue (uint16_t value) const { 131 | return this->writeRegister(0x25, (value >> 8) & 0xff) && this->writeRegister(0x26, value & 0xff); 132 | } 133 | uint16_t LOWValue () const { 134 | return (this->readRegister(0x25, 0) << 8) + this->readRegister(0x26, 0); 135 | } 136 | 137 | #ifndef NO_DS18B20 138 | bool Offset (int32_t value) const { 139 | return 140 | this->writeRegister(0x01, (value >> 24) & 0xff) && 141 | this->writeRegister(0x02, (value >> 16) & 0xff) && 142 | this->writeRegister(0x03, (value >> 8) & 0xff) && 143 | this->writeRegister(0x04, (value) & 0xff) 144 | ; 145 | } 146 | 147 | int32_t Offset () const { 148 | return 149 | ((int32_t)(this->readRegister(0x01, 0)) << 24) + 150 | ((int32_t)(this->readRegister(0x02, 0)) << 16) + 151 | ((int32_t)(this->readRegister(0x03, 0)) << 8 ) + 152 | ((int32_t)(this->readRegister(0x04, 0)) ) 153 | ; 154 | } 155 | #endif 156 | 157 | void defaults () { 158 | clear(); 159 | HIGHValue(830); 160 | LOWValue(420); 161 | #ifndef NO_DS18B20 162 | Offset(0); 163 | #endif 164 | } 165 | }; 166 | 167 | class WeatherEventMsg : public Message { 168 | public: 169 | void init(uint8_t msgcnt, uint8_t *h, bool batlow, uint8_t volt, __attribute__ ((unused)) int16_t temperature, __attribute__ ((unused)) int8_t offset) { 170 | 171 | #ifndef NO_DS18B20 172 | int16_t t = temperature + offset; 173 | DPRINT(F("+Temp C : ")); DDECLN(t); 174 | #endif 175 | DPRINT(F("+Battery V : ")); DDECLN(volt); 176 | #ifdef NO_DS18B20 177 | #define PAYLOAD_OFFSET 0 178 | #else 179 | #define PAYLOAD_OFFSET 2 180 | #endif 181 | 182 | Message::init(0xc + PAYLOAD_OFFSET + (DEVICE_CHANNEL_COUNT * 2), msgcnt, 0x53, (msgcnt % 20 == 1) ? (BIDI | WKMEUP) : BCAST, batlow ? 0x80 : 0x00, 0x41); 183 | 184 | #ifndef NO_DS18B20 185 | pload[0] = (t >> 8) & 0xff; 186 | pload[1] = (t) & 0xff; 187 | #endif 188 | 189 | pload[PAYLOAD_OFFSET] = (volt) & 0xff; 190 | for (uint8_t s = 0; s < DEVICE_CHANNEL_COUNT; s++) { 191 | DPRINT(F("+Humidity (#")); DDEC(s + 1); DPRINT(F(") %: ")); DDECLN(h[s]); 192 | pload[1+PAYLOAD_OFFSET+(s * 2)] = 0x42 + s; 193 | pload[2+PAYLOAD_OFFSET+(s * 2)] = h[s] & 0xff; 194 | } 195 | } 196 | void init(uint8_t msgcnt, uint8_t *h, bool batlow, uint8_t volt) { 197 | init(msgcnt, h, batlow, volt, 0, 0); 198 | } 199 | }; 200 | 201 | class WeatherChannel : public Channel { 202 | public: 203 | WeatherChannel () : Channel() {} 204 | virtual ~WeatherChannel () {} 205 | 206 | void configChanged() { 207 | DPRINT(F("Config changed List1 (CH "));DDEC(number());DPRINTLN(F(")")); 208 | #ifndef NO_DS18B20 209 | if (number() == 1) { DPRINT(F("*Offset : ")); DDECLN(this->getList1().Offset()); } 210 | #endif 211 | if (number() > 1) { DPRINT(F("*HIGHValue : ")); DDECLN(this->getList1().HIGHValue()); } 212 | if (number() > 1) { DPRINT(F("*LOWValue : ")); DDECLN(this->getList1().LOWValue()); } 213 | } 214 | 215 | uint8_t status () const { 216 | return 0; 217 | } 218 | 219 | uint8_t flags () const { 220 | return 0; 221 | } 222 | }; 223 | 224 | class UType : public MultiChannelDevice { 225 | public: 226 | #ifndef NO_DS18B20 227 | Ds18b20 sensor[1]; 228 | #endif 229 | class SensorArray : public Alarm { 230 | UType& dev; 231 | 232 | public: 233 | uint8_t humidity[DEVICE_CHANNEL_COUNT]; 234 | SensorArray (UType& d) : Alarm(0), dev(d) {} 235 | virtual ~SensorArray () {} 236 | 237 | void measure() { 238 | //enable all moisture sensors 239 | for (uint8_t s = 0; s < sizeof(SENSOR_EN_PINS); s++) { 240 | digitalWrite(SENSOR_EN_PINS[s], HIGH); 241 | _delay_ms(5); 242 | } 243 | 244 | //wait a moment to settle 245 | _delay_ms(500); 246 | //now measure all sensors 247 | for (uint8_t s = 0; s < DEVICE_CHANNEL_COUNT; s++) { 248 | uint16_t sens_val = 0; 249 | 250 | //measure 8 times and calculate average 251 | for (uint8_t i = 0; i < 8; i++) { 252 | sens_val += analogRead(SENSOR_PINS[s]); 253 | _delay_ms(10); 254 | } 255 | sens_val /= 8; 256 | 257 | DPRINT(F("+Analog (#")); DDEC(s + 1); DPRINT(F("): ")); DDEC(sens_val); 258 | uint16_t upper_limit = dev.channel(s + 2).getList1().HIGHValue(); 259 | uint16_t lower_limit = dev.channel(s + 2).getList1().LOWValue(); 260 | if (sens_val > upper_limit) { 261 | humidity[s] = 0; 262 | DPRINTLN(F(" higher than limit!")); 263 | } 264 | else if (sens_val < lower_limit) { 265 | humidity[s] = 100; 266 | DPRINTLN(F(" lower than limit!")); 267 | } 268 | else { 269 | uint16_t range = upper_limit - lower_limit; 270 | uint32_t base = sens_val - lower_limit; 271 | uint8_t pct_inv = (base * 100) / range; 272 | humidity[s] = 100 - pct_inv; 273 | DPRINTLN(""); 274 | } 275 | 276 | //humidity[s] = random(0,100); 277 | 278 | } 279 | //disable all moisture sensors 280 | for (uint8_t s = 0; s < sizeof(SENSOR_EN_PINS); s++) 281 | digitalWrite(SENSOR_EN_PINS[s], LOW); 282 | 283 | #ifndef NO_DS18B20 284 | Ds18b20::measure(dev.sensor, 1); 285 | #endif 286 | } 287 | 288 | virtual void trigger (__attribute__ ((unused)) AlarmClock& clock) { 289 | measure(); 290 | tick = delay(); 291 | WeatherEventMsg& msg = (WeatherEventMsg&)dev.message(); 292 | #ifndef NO_DS18B20 293 | msg.init(dev.nextcount(), humidity, dev.battery().low(), dev.battery().current(), dev.sensor[0].temperature(), dev.channel(1).getList1().Offset()); 294 | #else 295 | msg.init(dev.nextcount(), humidity, dev.battery().low(), dev.battery().current()); 296 | #endif 297 | dev.send(msg, dev.getMasterID()); 298 | sysclock.add(*this); 299 | } 300 | 301 | uint32_t delay () { 302 | //Sendeintervall festlegen 303 | uint16_t _txDelay = max(dev.getList0().Sendeintervall(), 1); 304 | return seconds2ticks(_txDelay * 60 * SYSCLOCK_FACTOR); 305 | } 306 | 307 | } sensarray; 308 | 309 | 310 | typedef MultiChannelDevice TSDevice; 311 | UType(const DeviceInfo& info, uint16_t addr) : TSDevice(info, addr), sensarray(*this) {} 312 | virtual ~UType () {} 313 | 314 | void init (Hal& hal) { 315 | TSDevice::init(hal); 316 | for (uint8_t s = 0; s < DEVICE_CHANNEL_COUNT; s++) 317 | pinMode(SENSOR_PINS[ s ], INPUT); 318 | 319 | for (uint8_t s = 0; s < sizeof(SENSOR_EN_PINS); s++) 320 | pinMode(SENSOR_EN_PINS[s], OUTPUT); 321 | 322 | #ifndef NO_DS18B20 323 | uint8_t sensorcount = Ds18b20::init(oneWire, sensor, 1); 324 | DPRINT(F("DS18B20 Sensor "));DPRINTLN((sensorcount > 0) ? F("OK"):F("ERROR")); 325 | #endif 326 | sensarray.set(seconds2ticks(5)); 327 | sysclock.add(sensarray); 328 | } 329 | 330 | virtual void configChanged () { 331 | TSDevice::configChanged(); 332 | DPRINT(F("*LOW BAT Limit: ")); 333 | DDECLN(this->getList0().lowBatLimit()); 334 | this->battery().low(this->getList0().lowBatLimit()); 335 | DPRINT(F("*Sendeintervall: ")); DDECLN(this->getList0().Sendeintervall()); 336 | 337 | } 338 | }; 339 | 340 | UType sdev(devinfo, 0x20); 341 | ConfigButton cfgBtn(sdev); 342 | 343 | void setup () { 344 | DINIT(57600, ASKSIN_PLUS_PLUS_IDENTIFIER); 345 | sdev.init(hal); 346 | DDEVINFO(sdev); 347 | buttonISR(cfgBtn, CONFIG_BUTTON_PIN); 348 | sdev.initDone(); 349 | } 350 | 351 | void loop() { 352 | bool worked = hal.runready(); 353 | bool poll = sdev.pollRadio(); 354 | 355 | if ( worked == false && poll == false ) { 356 | if ( hal.battery.critical() ) { 357 | DPRINT(F("Battery critical! "));DDECLN(hal.battery.current()); 358 | Serial.flush(); 359 | hal.activity.sleepForever(hal); 360 | } 361 | hal.activity.savePower>(hal); 362 | } 363 | } 364 | -------------------------------------------------------------------------------- /Images/SEN0193-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jp112sdl/HB-UNI-Sen-CAP-MOIST/61a86beb886eafad0f9390c59302a53f03121ff5/Images/SEN0193-line.png -------------------------------------------------------------------------------- /Images/arduino_ide_serialmonitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jp112sdl/HB-UNI-Sen-CAP-MOIST/61a86beb886eafad0f9390c59302a53f03121ff5/Images/arduino_ide_serialmonitor.png -------------------------------------------------------------------------------- /Images/aufbau1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jp112sdl/HB-UNI-Sen-CAP-MOIST/61a86beb886eafad0f9390c59302a53f03121ff5/Images/aufbau1.jpg -------------------------------------------------------------------------------- /Images/aufbau2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jp112sdl/HB-UNI-Sen-CAP-MOIST/61a86beb886eafad0f9390c59302a53f03121ff5/Images/aufbau2.jpg -------------------------------------------------------------------------------- /Images/aufbau3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jp112sdl/HB-UNI-Sen-CAP-MOIST/61a86beb886eafad0f9390c59302a53f03121ff5/Images/aufbau3.jpg -------------------------------------------------------------------------------- /Images/ccu_addon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jp112sdl/HB-UNI-Sen-CAP-MOIST/61a86beb886eafad0f9390c59302a53f03121ff5/Images/ccu_addon.png -------------------------------------------------------------------------------- /Images/ccu_einstellungen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jp112sdl/HB-UNI-Sen-CAP-MOIST/61a86beb886eafad0f9390c59302a53f03121ff5/Images/ccu_einstellungen.png -------------------------------------------------------------------------------- /Images/ccu_geraete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jp112sdl/HB-UNI-Sen-CAP-MOIST/61a86beb886eafad0f9390c59302a53f03121ff5/Images/ccu_geraete.png -------------------------------------------------------------------------------- /Images/ccu_status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jp112sdl/HB-UNI-Sen-CAP-MOIST/61a86beb886eafad0f9390c59302a53f03121ff5/Images/ccu_status.png -------------------------------------------------------------------------------- /Images/wiring2.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jp112sdl/HB-UNI-Sen-CAP-MOIST/61a86beb886eafad0f9390c59302a53f03121ff5/Images/wiring2.fzz -------------------------------------------------------------------------------- /Images/wiring2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jp112sdl/HB-UNI-Sen-CAP-MOIST/61a86beb886eafad0f9390c59302a53f03121ff5/Images/wiring2.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HB-UNI-Sen-CAP-MOIST 2 | ## Funk "kapazitiver Bodenfeuchtesensor" mit _optionalem_ Temperatursensor DS18B20 für die Integration in HomeMatic 3 | #### (mit bis zu 7* Sensoren pro Gerät) 4 | _*6 bei zusätzlicher Verwendung des Temperatursensors_ 5 | 6 | Um die Geräteunterstützung zu aktivieren, wird die aktuellste Version des [JP-HB-Devices Addon](https://github.com/jp112sdl/JP-HB-Devices-addon/releases/latest) (mind. Version 2.7) benötigt! 7 |
8 | 9 | ## Verdrahtung 10 | ![wiring](Images/wiring2.png) 11 | 12 | ## benötigte Hardware 13 | * 1x Arduino Pro Mini **ATmega328P (3.3V / 8MHz)** 14 | * 1x CC1101 Funkmodul **(868 MHz)** 15 | * 1x FTDI Adapter (wird nur zum Flashen benötigt) 16 | * 1x Taster (beliebig... irgendwas, das beim Draufdrücken schließt :smiley:) 17 | * 1x LED 18 | * 1x Widerstand 330 Ohm (R1) 19 | * 1x Widerstand 100k (R2) 20 | * 1x Widerstand 470k (R3) 21 | * 1x (optional) Widerstand 4,7k (R4) _nur bei Verwendung mit DS18B20 Temperatursensor_ 22 | * 1x (optional) DS18B20 Temperatursensor 23 | * 1x ... 7x kapazitiver Feuchtesensor (0...3V Ausgangsspannung) [ebay](https://www.ebay.de/itm/152873639264) 24 | 25 | Um die [Batterielebensdauer zu erhöhen](https://asksinpp.de/Grundlagen/01_hardware.html#stromversorgung), ist es unbedingt notwendig, die LEDs vom Arduino Pro Mini von der Platine zu entfernen! 26 | 27 | 28 | Die Stromversorgung besteht bspw. aus **3x** AA(A)-**Batterien** (oder **4x 1.2V Akkus**).
29 | 30 | ## Platine 31 |
32 | ...gibts von [>>>Marco<<<](https://github.com/stan23/myPCBs/tree/master/HB-UNI-Sen-CAP-MOIST-T) 33 | 34 | 35 | ## Code flashen 36 | - [AskSinPP Library](https://github.com/pa-pa/AskSinPP) in der Arduino IDE installieren (master-Branch ab 13.05.2019 verwenden!) 37 | - Achtung: Die Lib benötigt selbst auch noch weitere Bibliotheken, siehe [README](https://github.com/pa-pa/AskSinPP#required-additional-arduino-libraries). 38 | - [Projekt-Datei](https://raw.githubusercontent.com/jp112sdl/HB-UNI-Sen-CAP-MOIST/master/HB-UNI-Sen-CAP-MOIST.ino) herunterladen. 39 | - Arduino IDE öffnen 40 | - Heruntergeladene Projekt-Datei öffnen 41 | - Werkzeuge 42 | - Board: Arduino Pro or Pro Mini 43 | - Prozessor: ATmega328P (3.3V 8MHz) 44 | - Port: entsprechend FTDI Adapter 45 | einstellen 46 | - ggf. Anpassungen im Code durchführen (z.B. bei mehreren Sensoren) 47 | - Code-Optionen: 48 | - wenn **kein** Temperatursensor angeschlossen werden soll, sind die Kommentarzeichen zu entfernen:
`// #define NO_DS18B20 //use model without temperature sensor` 49 | - Pins anpassen:
`const uint8_t SENSOR_PINS[] {15, 16, 17}; //AOut Pins der Sensoren (hier A1, A2 und A3)`
50 | `//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[] {6};` 51 | - Menü "Sketch" -> "Hochladen" auswählen. 52 | 53 | 54 | ## Gerät anlernen 55 | Wenn alles korrekt verkabelt und das Addons installiert ist, kann das Gerät angelernt werden.
56 | Über den Button "Gerät anlernen" in der WebUI öffnet sich der Anlerndialog.
57 | Button "HM Gerät anlernen" startet den Anlernmodus.
58 | Nun ist der Taster (an Pin D8) kurz zu drücken.
59 | Die LED leuchtet für einen Moment.
60 | Anschließend ist das Gerät im Posteingang zu finden.
61 | Dort auf "Fertig" geklickt, wird es nun in der Geräteübersicht aufgeführt.
62 | ![addon](Images/ccu_geraete.png) 63 |

64 | ## Kalibrierung 65 | Der [Hersteller des Sensors](https://www.dfrobot.com/wiki/index.php/Capacitive_Soil_Moisture_Sensor_SKU:SEN0193) sieht eine manuelle Kalibrierung vor.
66 | Es müssen die Spannungswerte für beide Feuchte-Grenzen (trocken / nass) ermittelt werden.
67 | Der Wert wird beim Starten des Arduino Pro Mini im seriellen Monitor (57600 Baud) angezeigt.
68 | Siehe `+Analog   (#n):`
69 | ![sermon](Images/arduino_ide_serialmonitor.png) 70 | 71 | Zur Kalibrierung startet man nun den Arduino Pro Mini ein Mal mit trockenen Sensoren und ein Mal in ein Glas Wasser eingetaucht. 72 | 73 | _Der Wert im Trockenen muss höher sein als im Nassen!_ 74 | 75 |

76 | Beide Werte können nun in der WebUI-Gerätekonfiguration eingegeben werden. 77 | 78 | ## Einstellungen 79 | - Gerät: 80 | - Low Bat Schwelle 81 |  - ~3.7V 82 | - Das Sendeintervall kann zwischen 1 und 1440 Minuten eingestellt werden.
83 | - je Kanal: 84 | - HIGH Value ist der gemessene Analogwert, wenn der Sensor trocken ist.
85 | - LOW Value ist der gemessene Analogwert, wenn der Sensor komplett nass (in Wasser eingetaucht) ist.
86 | 87 | ![addon](Images/ccu_einstellungen.png) 88 |

89 | ## Wert anzeigen 90 | Unter "Status und Bedienung" -> "Geräte" kann der Feuchtigkeitswert angezeigt werden.
91 | Damit man den Datenpunkt auch in Diagrammen verwenden kann, habe ich den systeminternen Datentyp `HUMIDITY` verwendet. 92 | Das hat jedoch einen kleinen Schönheitsfehler zur Folge: Die Bezeichnung lautet "Rel. Luftfeuchte". 93 | Damit kann man wohl leben... :) 94 | ![addon](Images/ccu_status.png) 95 | 96 | 97 | 98 | Eine Verwendung in Programmen ist ebenfalls möglich. 99 | 100 | ## Gehäuse 101 | - [Gehäuse von "tonischabloni"](https://www.thingiverse.com/thing:3633804) auf Thingiverse:
102 | 103 |
104 | 105 | ## Mein Prototyp 106 | 107 | ![aufbau1](Images/aufbau1.jpg) 108 | 109 | ![aufbau2](Images/aufbau2.jpg) 110 | 111 | ![aufbau3](Images/aufbau3.jpg) 112 | --------------------------------------------------------------------------------