mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.1.2 RAIN
This commit is contained in:
parent
f336566e4c
commit
0423bd1512
@ -6,6 +6,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.1.2] - 2022-12-06
|
||||
- add powerPin to constructor. Optional.
|
||||
- add powerPin example
|
||||
- add interrupt example (using DO = digital Out)
|
||||
- add digital out polling example
|
||||
- update readme.md (lower voltage == wetter)
|
||||
- fix version number
|
||||
- fix percentage() => 0% == DRY and 100% == WET
|
||||
- add get- and setDryReference() for better percentage() behaviour.
|
||||
- update keywords.txt
|
||||
|
||||
|
||||
## [0.1.1] - 2022-12-03
|
||||
- change levels to milliVolts (uint16_t).
|
||||
- rewrite setLevel(milliVolts) and getLevel().
|
||||
@ -14,7 +26,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- update keywords.txt
|
||||
- add delta() => delta with previous read().
|
||||
|
||||
|
||||
## [0.1.0] - 2022-12-03
|
||||
- initial version
|
||||
|
||||
|
@ -13,45 +13,85 @@ RAIN is an Arduino library for a rain sensor (analog).
|
||||
|
||||
## Description
|
||||
|
||||
A rain sensor is a relative simple device.
|
||||
A rain sensor (FC-37, YL-83, HM-RD) is a relative simple device.
|
||||
It measures the resistance of a number of wires when these are put in a liquid (water)
|
||||
The device converts the resistance to a voltage typical 0 .. 5 Volt.
|
||||
The more the wires are covered by the liquid, the higher the voltage.
|
||||
The more the wires are covered by the liquid, the lower the voltage.
|
||||
0.0 Volt is WET, and a high voltage is DRY.
|
||||
|
||||
The breakout I used to test also has a digital output, which goes HIGH if a certain
|
||||
threshold (to be set with a potentiometer on the breakout) is reached.
|
||||
The meaning / potential of this digital-out for the library needs to be investigated.
|
||||
The breakout (LM393 comparator) I used to test also has a digital output,
|
||||
which goes LOW if a threshold (to be set with a potentiometer on the breakout) is reached.
|
||||
|
||||
The library is EXPERIMENTAL as it needs more testing.
|
||||
(changes of the interface are definitely possible).
|
||||
|
||||
## Hardware connection
|
||||
|
||||
Typical connection
|
||||
|
||||
```
|
||||
Processor LM393 SENSOR FC-37
|
||||
+-------------+ +----------+ +---------------------+
|
||||
| | | | | |
|
||||
| GND |----->| GND | | |
|
||||
| powerPin |----->| 5V |-----| |
|
||||
| analogIn |<-----| AO | | |
|
||||
| | | |-----| |
|
||||
| digital in |<-----| DO | | |
|
||||
| | | | | |
|
||||
+-------------+ +----------+ +---------------------+
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Interface
|
||||
|
||||
- **RAIN(uint8_t port)** constructor.
|
||||
- **RAIN(uint8_t port, uint8_t powerPin = 255)** constructor.
|
||||
port is the internal analog port to use.
|
||||
powerPin is optional, but recommended.
|
||||
- **bool begin(float maxVoltage, uint16_t maxSteps)** sets the ADC parameters.
|
||||
Allows to be changed runtime, e.g. if voltage fluctuates the math can be adapted by calling **begin()** again.
|
||||
Might be a separate **setVoltage()** is more efficient.
|
||||
- **float raw(uint8_t times = 1)** makes 1 or more measurements and averages them.
|
||||
returned value is the average number of ADC steps.
|
||||
- **float read(uint8_t times = 1)** makes 1 or more measurements, averages them and convert the average to a voltage.
|
||||
THis voltage is returned, and also cached for **percentage()** and **getLevel()**.
|
||||
This voltage is returned, and also cached for **percentage()** and **getLevel()**.
|
||||
|
||||
|
||||
#### powerControl
|
||||
|
||||
Will only work if the **powerPin** is set in the constructor.
|
||||
|
||||
- **void powerOn()** switch the sensor on.
|
||||
- **void powerOff()** switch the sensor off.
|
||||
|
||||
The powerPin is used to switch the LM393 ON and OFF so the sensor is powered
|
||||
only when the sensor is read. That reduces corrosion and energy usage.
|
||||
Note: when the power is OFF, the digital-out cannot be used e.g. for interrupts.
|
||||
So check what your project needs.
|
||||
|
||||
Note: the powerOn() delays for 100us to give the LM393 time to stabilize.
|
||||
Adjust this if needed.
|
||||
|
||||
|
||||
#### Analysis
|
||||
|
||||
- **void setDryReference(float dryRef)** used to calibrate the voltage when the sensor is dry.
|
||||
Use **read()** to read / calibrate the voltage when the sensor is dry.
|
||||
If not explicitly set, the max ADC voltage os used.
|
||||
- **void getDryReference()** returns the set value.
|
||||
- **float percentage()** returns the last **read()** to a percentage.
|
||||
Note one needs to call read() again to get a new value as this uses a cached value.
|
||||
- **float delta()** returns the delta voltage compared to previous read.
|
||||
It give the first derivative of the signal. How fast does it rise.
|
||||
- **bool setLevel(uint8_t nr, uint16_t millivolts)** allows a user to set 5 voltage levels in milliVolts.
|
||||
- **bool setLevel(uint8_t nr, uint16_t millivolts)** allows a user to set 4 voltage levels in milliVolts.
|
||||
- **uint8_t getLevel()**
|
||||
Returns the level of the current cached voltage.
|
||||
See example.
|
||||
|
||||
The library allows the user to set 5 thresholds or levels for the **getLevel()** function.
|
||||
These 5 levels can help to control behaviour at a certain level.
|
||||
Typical levels are almost empty, to almost full and full.
|
||||
The library allows the user to set 4 thresholds or levels for the **getLevel()** function.
|
||||
These 4 levels + 1 zero level can help to control behaviour of a system at a certain level.
|
||||
Typical levels are almost empty, almost full and full.
|
||||
The level do not need to be on a linear mapping like 20% steps, if your project need
|
||||
other levels you can define these.
|
||||
|
||||
@ -68,7 +108,18 @@ See https://github.com/RobTillaart/MultiMap
|
||||
|
||||
## Operation
|
||||
|
||||
The examples show the basic working of the functions.
|
||||
The examples show the basic working of the functions of the library.
|
||||
|
||||
The rain sensor can be used in different types of projects.
|
||||
Every project has a typical orientation of the sensor.
|
||||
|
||||
| project | orientation | measurement |
|
||||
|:-----------------|:----------------:|:-------------:|
|
||||
| rain sensor | angle e.g. 45° | polling
|
||||
| leak detection | horizontal | interrupt - digital OUT
|
||||
| water level | vertical | polling
|
||||
|
||||
For other applications it depends.
|
||||
|
||||
|
||||
## Future
|
||||
@ -76,19 +127,11 @@ The examples show the basic working of the functions.
|
||||
#### Must
|
||||
- update documentation
|
||||
- links etc.
|
||||
- add interrupt example for digital output capture.
|
||||
|
||||
|
||||
#### Should
|
||||
- optimizations
|
||||
- a lot of floats...==> more uint16_t millivolts?
|
||||
- add examples.
|
||||
- investigate possibilities of the digital output
|
||||
- how to include
|
||||
- example (see above)
|
||||
- improve the **percentage()** maxVoltage setter?
|
||||
- 2 different meanings of maxVoltage. For ADC and sensor out.
|
||||
- is the device linear? does percentage make sense if it is not?
|
||||
- a lot of floats...==> more uint16_t millivolts? (0.2.0)
|
||||
|
||||
|
||||
#### Could
|
||||
@ -104,10 +147,11 @@ The examples show the basic working of the functions.
|
||||
- different salinity
|
||||
- different liquids? which?
|
||||
- how linear is the device?
|
||||
|
||||
|
||||
#### Won't (unless requested)
|
||||
- example with multiMap
|
||||
- see multiMap library.
|
||||
- **incrLevel(nr, amount = 1)** + **decrLevel(nr, amount = 1)**
|
||||
to allow easier runtime tuning
|
||||
|
||||
#### Won't
|
||||
- example with multiMap
|
||||
- see multiMap library.
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo read + delta
|
||||
// URL: https://github.com/RobTillaart/RAIN
|
||||
//
|
||||
// e.g. use with Arduino IDE plotter tool.
|
||||
|
||||
|
||||
#include "rain.h"
|
||||
|
@ -19,6 +19,9 @@ void setup()
|
||||
Serial.println("EXPERIMENTAL:");
|
||||
|
||||
RS.begin(5.000, 1023);
|
||||
|
||||
// measured in an earlier run, adjust to your calibration.
|
||||
RS.setDryReference(3.5);
|
||||
}
|
||||
|
||||
|
||||
@ -33,3 +36,4 @@ void loop()
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -0,0 +1,38 @@
|
||||
//
|
||||
// FILE: rain_demo_powerpin.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo read power pin
|
||||
// URL: https://github.com/RobTillaart/RAIN
|
||||
|
||||
|
||||
#include "rain.h"
|
||||
|
||||
#define ANALOGPIN A0
|
||||
#define POWERPIN 7
|
||||
|
||||
RAIN RS(ANALOGPIN, POWERPIN);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("RAIN_LIB_VERSION: ");
|
||||
Serial.println(RAIN_LIB_VERSION);
|
||||
Serial.println("EXPERIMENTAL:");
|
||||
|
||||
RS.begin(5.000, 1023);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print(RS.read(), 3);
|
||||
Serial.print('\t');
|
||||
Serial.print(RS.percentage(), 1);
|
||||
Serial.print('\n');
|
||||
delay(100);
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -0,0 +1,48 @@
|
||||
//
|
||||
// FILE: rain_digital_out.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo digital out DO pin
|
||||
// URL: https://github.com/RobTillaart/RAIN
|
||||
|
||||
|
||||
#include "rain.h"
|
||||
|
||||
#define ANALOGPIN A0
|
||||
#define POWERPIN 7
|
||||
#define DIGIOUT 8
|
||||
|
||||
RAIN RS(ANALOGPIN, POWERPIN);
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("RAIN_LIB_VERSION: ");
|
||||
Serial.println(RAIN_LIB_VERSION);
|
||||
Serial.println("EXPERIMENTAL:");
|
||||
|
||||
RS.begin(5.000, 1023);
|
||||
|
||||
pinMode(DIGIOUT, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (digitalRead(DIGIOUT) == LOW)
|
||||
{
|
||||
Serial.print(millis());
|
||||
Serial.print('\t');
|
||||
Serial.print(RS.read(), 3);
|
||||
Serial.print('\t');
|
||||
Serial.print(RS.getLevel());
|
||||
Serial.print('\n');
|
||||
}
|
||||
delay(100);
|
||||
// other code here
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
57
libraries/rain/examples/rain_interrupt/rain_interrupt.ino
Normal file
57
libraries/rain/examples/rain_interrupt/rain_interrupt.ino
Normal file
@ -0,0 +1,57 @@
|
||||
//
|
||||
// FILE: rain_interrupt.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo rain_interrupt digital out
|
||||
// URL: https://github.com/RobTillaart/RAIN
|
||||
|
||||
|
||||
#include "rain.h"
|
||||
|
||||
#define ANALOGPIN A0
|
||||
#define POWERPIN 7
|
||||
#define DIGIOUT_IRQ 2
|
||||
|
||||
RAIN RS(ANALOGPIN, POWERPIN);
|
||||
|
||||
volatile bool waterDetected = false;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("RAIN_LIB_VERSION: ");
|
||||
Serial.println(RAIN_LIB_VERSION);
|
||||
Serial.println("EXPERIMENTAL:");
|
||||
|
||||
RS.begin(5.000, 1023);
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(DIGIOUT_IRQ), isr, FALLING);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (waterDetected)
|
||||
{
|
||||
Serial.print(millis());
|
||||
Serial.print('\t');
|
||||
Serial.print(RS.read(), 3);
|
||||
Serial.print('\t');
|
||||
Serial.print(RS.getLevel());
|
||||
Serial.print('\n');
|
||||
waterDetected = false;
|
||||
}
|
||||
delay(100);
|
||||
// other code here
|
||||
}
|
||||
|
||||
|
||||
void isr()
|
||||
{
|
||||
waterDetected = true;
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -46,14 +46,14 @@ void loop()
|
||||
int level = RS.getLevel();
|
||||
switch (level)
|
||||
{
|
||||
case 4:
|
||||
case 0: // max WET
|
||||
if (prevLevel != level)
|
||||
{
|
||||
Serial.println("Pump speed 100%");
|
||||
}
|
||||
analogWrite(PUMP_PIN, 255);
|
||||
break;
|
||||
case 3:
|
||||
case 1:
|
||||
if (prevLevel != level)
|
||||
{
|
||||
Serial.println("Pump speed 90%");
|
||||
@ -65,20 +65,20 @@ void loop()
|
||||
{
|
||||
Serial.println("Pump speed 75%");
|
||||
}
|
||||
analogWrite(PUMP_PIN, 195); // ~75%
|
||||
analogWrite(PUMP_PIN, 195);
|
||||
break;
|
||||
case 1:
|
||||
case 3:
|
||||
if (prevLevel != level)
|
||||
{
|
||||
Serial.println("Start pumping");
|
||||
Serial.println("Pump speed 50%");
|
||||
}
|
||||
analogWrite(PUMP_PIN, 130); // ~50%
|
||||
analogWrite(PUMP_PIN, 130);
|
||||
break;
|
||||
case 0:
|
||||
case 4: // DRY
|
||||
default:
|
||||
if (prevLevel != level)
|
||||
{
|
||||
Serial.println("Stop pumping");
|
||||
Serial.println("Stopped pumping");
|
||||
}
|
||||
analogWrite(PUMP_PIN, 0);
|
||||
break;
|
||||
|
@ -8,10 +8,18 @@ begin KEYWORD2
|
||||
raw KEYWORD2
|
||||
read KEYWORD2
|
||||
|
||||
setDryReference KEYWORD2
|
||||
getDryReference KEYWORD2
|
||||
|
||||
percentage KEYWORD2
|
||||
delta KEYWORD2
|
||||
|
||||
setLevel KEYWORD2
|
||||
getLevel KEYWORD2
|
||||
|
||||
powerOn KEYWORD2
|
||||
powerOff KEYWORD2
|
||||
|
||||
# Constants (LITERAL1)
|
||||
RAIN_LIB_VERSION LITERAL1
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "RAIN",
|
||||
"keywords": "RAIN, wet",
|
||||
"description": "Arduino library for rain sensor. (analog)",
|
||||
"keywords": "RAIN, wet, FC-37, YL-83, HM-RD, LM393",
|
||||
"description": "Arduino library for FC-37 analog rain sensor and compatibles.",
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/RAIN.git"
|
||||
},
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
|
@ -1,10 +1,10 @@
|
||||
name=RAIN
|
||||
version=0.1.1
|
||||
version=0.1.2
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for rain sensor (analog).
|
||||
paragraph=wet, wetness.
|
||||
category=Signal Input/Output
|
||||
sentence=Arduino library for FC-37 analog rain sensor and compatibles.
|
||||
paragraph=wet, wetness, FC-37, YL-83, HM-RD, LM393.
|
||||
category=Sensors
|
||||
url=https://github.com/RobTillaart/RAIN
|
||||
architectures=*
|
||||
includes=rain.h
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// FILE: rain.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// VERSION: 0.1.2
|
||||
// DATE: 2021-12-03
|
||||
// PURPOSE: Arduino library for a rain sensor
|
||||
// URL: https://github.com/RobTillaart/RAIN
|
||||
@ -10,11 +10,13 @@
|
||||
|
||||
#include "rain.h"
|
||||
|
||||
RAIN::RAIN(uint8_t port)
|
||||
RAIN::RAIN(uint8_t port, uint8_t powerPin)
|
||||
{
|
||||
_port = port;
|
||||
_powerPin = powerPin;
|
||||
_maxVoltage = 5;
|
||||
_maxSteps = 1023;
|
||||
_dryRefVoltage = _maxVoltage;
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +25,13 @@ bool RAIN::begin(float maxVoltage, uint16_t maxSteps)
|
||||
_maxVoltage = maxVoltage;
|
||||
_maxSteps = maxSteps;
|
||||
_mVstep = _maxVoltage / _maxSteps;
|
||||
_dryRefVoltage = _maxVoltage;
|
||||
|
||||
if (_powerPin != 255)
|
||||
{
|
||||
pinMode(_powerPin, OUTPUT);
|
||||
powerOn();
|
||||
}
|
||||
read();
|
||||
return true;
|
||||
}
|
||||
@ -32,10 +41,14 @@ float RAIN::raw(uint8_t times)
|
||||
{
|
||||
if (times == 0) times = 1;
|
||||
float sum = 0;
|
||||
|
||||
powerOn();
|
||||
for (int i = 0; i < times; i++)
|
||||
{
|
||||
sum += analogRead(_port);
|
||||
}
|
||||
powerOff();
|
||||
|
||||
if (times > 1) sum /= times;
|
||||
return sum;
|
||||
}
|
||||
@ -49,9 +62,23 @@ float RAIN::read(uint8_t times)
|
||||
}
|
||||
|
||||
|
||||
void RAIN::setDryReference(float dryRef)
|
||||
{
|
||||
_dryRefVoltage = dryRef;
|
||||
}
|
||||
|
||||
|
||||
float RAIN::getDryReference()
|
||||
{
|
||||
return _dryRefVoltage;
|
||||
}
|
||||
|
||||
|
||||
float RAIN::percentage()
|
||||
{
|
||||
return _voltage * 100.0 / _maxVoltage;
|
||||
float p = 100.0 - (_voltage * 100.0 / _dryRefVoltage);
|
||||
if (p < 0) p = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
@ -81,5 +108,24 @@ uint8_t RAIN::getLevel()
|
||||
}
|
||||
|
||||
|
||||
void RAIN::powerOn()
|
||||
{
|
||||
if (_powerPin != 255)
|
||||
{
|
||||
digitalWrite(_powerPin, HIGH);
|
||||
delayMicroseconds(100); // time to stabilize, adjust if needed.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RAIN::powerOff()
|
||||
{
|
||||
if (_powerPin != 255)
|
||||
{
|
||||
digitalWrite(_powerPin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: rain.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// VERSION: 0.1.2
|
||||
// DATE: 2022-11-23
|
||||
// PURPOSE: Arduino library for rain sensor (analog).
|
||||
// URL: https://github.com/RobTillaart/RAIN
|
||||
@ -12,13 +12,15 @@
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
#define RAIN_LIB_VERSION (F("0.1.0"))
|
||||
#define RAIN_LIB_VERSION (F("0.1.2"))
|
||||
|
||||
|
||||
class RAIN
|
||||
{
|
||||
public:
|
||||
RAIN(uint8_t port);
|
||||
// port = analogPort,
|
||||
// powerPin is optional, 255 == not used => see readme.md
|
||||
RAIN(uint8_t port, uint8_t powerPin = 255);
|
||||
|
||||
// set the ADC parameters
|
||||
// can be changed runtime, e.g if voltage fluctuates.
|
||||
@ -27,29 +29,45 @@ public:
|
||||
// returns steps
|
||||
float raw(uint8_t times = 1);
|
||||
// returns voltage
|
||||
// the lower the voltage the wetter.
|
||||
float read(uint8_t times = 1);
|
||||
|
||||
|
||||
// ANALYSIS
|
||||
// returns last read value as percentage of maxVoltage.
|
||||
// indicating wetness?
|
||||
// it assumes / implies linear behaviour
|
||||
// read the sensor when it is dry to get a reference (calibration).
|
||||
// will be used by percentage(), can be used to setLevel().
|
||||
void setDryReference(float dryRef);
|
||||
float getDryReference();
|
||||
|
||||
// returns last read value as percentage of DryReference (if set).
|
||||
// indicating wetness 0 == DRY 100 == WET
|
||||
// percentage assumes / implies "linear" behaviour
|
||||
float percentage();
|
||||
|
||||
// delta with respect to previous read().
|
||||
float delta();
|
||||
|
||||
|
||||
// level = 1..4 (level 0 == 0 Volt)
|
||||
// level = 1..4
|
||||
// level 0 == 0 Volt ==> WET)
|
||||
// level 4 ==> DRY
|
||||
// user is responsible that values are increasing voltages.
|
||||
bool setLevel(uint8_t nr, uint16_t milliVolts);
|
||||
uint8_t getLevel();
|
||||
|
||||
// will only work when set in constructor.
|
||||
void powerOn();
|
||||
void powerOff();
|
||||
|
||||
|
||||
private:
|
||||
uint8_t _port;
|
||||
uint8_t _powerPin = 255; // 255 means not set.
|
||||
float _maxVoltage;
|
||||
uint16_t _maxSteps;
|
||||
float _mVstep;
|
||||
float _voltage;
|
||||
float _dryRefVoltage;
|
||||
float _previous;
|
||||
uint16_t _level[5] = { 0, 1000, 2000, 3000, 4000 }; // millivolts
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user