Skip to content

Commit

Permalink
vn0.3.5
Browse files Browse the repository at this point in the history
  • Loading branch information
Phil Bowles committed Feb 20, 2020
1 parent b929f39 commit 814494c
Show file tree
Hide file tree
Showing 15 changed files with 222 additions and 43 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ Version **0.3.5** [Release Notes](changelog.txt) **MUST UPGRADE TO [H4 library](

![H4PluginsFF](/assets/h4plugins.jpg)

Think of this as "IOT Lego" for [**H4**](https://github.com/philbowles/H4) - and if you are not already using H4's advanced scheduling and timing features, why not? Get it now from the link above, as you will need it to use the H4Plugins system.
Think of this as "IOT Lego" or an "IOT Swiss Army Knife" (or both) for [**H4**](https://github.com/philbowles/H4) - and if you are not already using H4's advanced scheduling and timing features, why not? Get it now from the link above, as you will need it to use the H4Plugins system.

H4Plugins includes modules for WiFi + OTA, Webserver, MQTT, 14 different types of GPIO handling, voice control and diagnostics. By "plugging " together only the required modules, you can rapidly build your own custom firmware or IOT app. Everything you build will be stable and responsive: the plugins work together to allow multiple simultaneous processes to run, so ***no more WDT resets***! As your experience grows you can extend your app / firmware with H4Plugins' well-documented API and runtime command system. Let's see H4Plugins being used as replacement firmware for a SONOFF Basic switch.
H4Plugins includes modules for WiFi + OTA, Webserver, MQTT, 15 different types of GPIO handling, voice control and diagnostics. By "plugging " together only the required modules, you can rapidly build your own custom firmware or IOT app. Everything you build will be stable and responsive: the plugins work together to allow multiple simultaneous processes to run, so ***no more WDT resets***! As your experience grows you can extend your app / firmware with H4Plugins' well-documented API and runtime command system. Let's see H4Plugins being used as replacement firmware for a SONOFF Basic switch.

What follows is the *entire H4Plugins code* - despite the fact it might look like there is something missing, there is not. The code as shown compiles to produce firmware that can be uploaded directly to any / all of your SONOFF devices and provides:

Expand Down Expand Up @@ -49,7 +49,7 @@ As you can see, all you need to do is list the modules you want (in the right or
The modular design of H4's plugin architecture minimises scarce resources in low-memory MCU targets: You only compile in what you need with a simple `#include`. Detailed diagnostics can be easily included and controlled at runtime via the serial console, HTTP REST or MQTT depending on which options you choose. It is built on top of the very stable [H4](https://github.com/philbowles/H4) timer/scheduler which traces its ancestry back to "Esparto" - of which one user recently said: *"and now have Esparto modules with months of uptime without an issue"*.
There are 40 example sketches demonstrating all the features and the API of all of the plugins. They should be used both as a template for your own sketches and as a learning resource.
There are 44 example sketches demonstrating all the features and the API of all of the plugins. They should be used both as a template for your own sketches and as a learning resource.
Users are strongly recommended to work through them in the order [listed below](readme.md#current-plugins-februrary-2020)
Expand Down Expand Up @@ -160,7 +160,7 @@ Or:
* [ESP32 AsyncUDP Library](https://github.com/espressif/arduino-esp32/tree/master/libraries/AsyncUDP)
* [ESP32 AsyncTCP Library](https://github.com/me-no-dev/AsyncTCP)
Depending on what target you are compiling for
Depending on what target you are compiling for (if both, then downlaod all libraries above)
And:
* [ESPAsyncWebServer](https://github.com/philbowles/ESPAsyncWebServer) * See note
Expand Down
19 changes: 12 additions & 7 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@

2020/02/19 0.3.6
bugfix
Polled not getting value on fake event when in analog mode
new
GPIO types
AnalogThreshold + new example
AnalogThresholdThing + new example

2020/02/19 0.3.5
breaking changes:
h4/factory moved to serialcmd from wifi // update docs!
changed
persistentStorage plugin
persistentStorage plugin + new example
2020/02/18 0.3.4
breaking changes:
1. _hasName removed from H4: MUST upgrade to 0.4.1
Expand Down Expand Up @@ -39,19 +48,15 @@
than a ground-up rewrite :)

TODO:
H4
rebootChain->forward_list? (watch size!)
LONGTERM
heaplogger
remote client get
sql logger
rf bridge
signal on no spiffs
template for hooking?
proper condl diags

diag out all dumps in GPIO
fix switch.ps1 to use soap etc (revert a la esparto)
take always ignore out of TS
SOONER
lots of const string&
find easy way to get FS space etc on ESP32
SOONER
2 changes: 2 additions & 0 deletions docs/h43fnb.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ A "long" press - anything over 5 seconds** - starts the LED flashing extremely r

# Usage

H4P_ThreeFunctionButton is a specialised example of an IOT "Thing" - you should read ["Things vs Switches"](things.md) before continuing

```cpp
#include<H4Plugins.h>
H4_USE_PLUGINS
Expand Down
26 changes: 26 additions & 0 deletions docs/h4gm.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Let's face it: there are only so many things you can do with a GPIO pin! Yes, th

GPIOManager currently provides behaviours for:

* AnalogThreshold - send 0 or 1 depending on raw analog value > or < user-defined limit
* Circular - Counts 1 - N, 1 - N etc
* Debounced - Eliminates switch bounce
* Encoder - Standard quadrature rotary encoder
Expand All @@ -67,6 +68,7 @@ GPIOManager currently provides behaviours for:

You should also read [Things vs Switches](things.md) which explains how some of the above strategies can be autmatically tied/bound/linked to predefined output actions. In it you will find how to use these variants of the above, each of which send an ON or OFF command to a linked output handler

* AnalogThresholdThing - binds a AnalogThreshold input to a BinarySwitch or UPNPSwitch output
* DebouncedThing - binds a Debounced input to a BinarySwitch or UPNPSwitch output
* EncoderThing - binds a Encoder input to a BinarySwitch or UPNPSwitch output
* LatchingThing - binds a Latching input to a BinarySwitch or UPNPSwitch output
Expand Down Expand Up @@ -270,6 +272,25 @@ This strategy can also do an `analogRead` if required: `state` will hold the raw
---
### **AnalogThreshold**
**AnalogThreshold** is a specialised version of **Polled**. As with **Polled** it has its state checked periodically but it then converts the raw analog value to a 0 or a 1 and compares it with a threshhold value. It will only execute the callback function if the > or < test against the threshold succeeds.
#### Additional fields for AnalogThreshold
`uint32_t limit; // The threshold value`
The constructor has a `compare` parameter which can be either `H4GM_LESS` or `H4GM_GREATER`
* If the raw value of the encoder is 77 and you specify a limit of 100 and use `H4GM_LESS` then the callback will receive 1 as 77 is less than 100
* If the raw value of the encoder is 77 and you specify a limit of 100 and use `H4GM_GREATER` then the callback will receive 0 as 77 is NOT greater than 100
* If the raw value of the encoder is 100 and you specify a limit of 512 and use `H4GM_LESS` then the callback will receive 1 as 100 is less than 512
* If the raw value of the encoder is 100 and you specify a limit of 512 and use `H4GM_GREATER` then the callback will receive 0 as 100 is NOT greater than 512
[Example Code](../examples/H4GM_AnalogThreshold/H4GM_AnalogThreshold.ino)
---
### **Encoder**
Manages a rotary encoder, including all necessary debouncing and decoding. You get called with additional field `encoderValue` of -1 for every anti-clockwise click or +1 for clockwise. It's that simple. Obviously it requires two physical pins but one single call does everything for you.
Expand All @@ -279,6 +300,7 @@ It also has a variant that takes the name of an `int` variable instead of a call
#### Additional fields for Encoder
`int encoderValue; // +1 clockwise click. -1 anti-clockwise`
[Example Code](../examples/H4GM_Encoder/H4GM_Encoder.ino)
---
Expand Down Expand Up @@ -315,6 +337,7 @@ setPercent // manually set value to % of max - min
setCenter // manully set the value to the mid-point (max - min / 2)
```

[Example Code](../examples/H4GM_EncoderAuto/H4GM_EncoderAuto.ino)

---
Expand Down Expand Up @@ -375,6 +398,7 @@ For simplicity the code calls another plugin [H4P_FlasherController](../h4fc) to
`int stage; // current table entry not exceeding held time`

`uint32_t held; // Number of microseconds GPIO was held ON`

[Example Code](../examples/H4GM_Multistage/H4GM_Multistage.ino)

---
Expand Down Expand Up @@ -411,6 +435,8 @@ void toggle(uint8_t p); // reverse current logical state
//
// Strategies
//
AnalogThresholdPin* AnalogThreshold(uint8_t p,uint32_t freq,uint32_t threshold,H4GM_COMPARE compare,H4GM_FN_EVENT callback);//
AnalogThresholdPin* AnalogThresholdThing(uint8_t p,uint32_t freq,uint32_t threshold,H4GM_COMPARE compare,H4P_BinaryThing* btp);//
CircularPin* Circular(uint8_t p,uint8_t mode,H4GM_SENSE sense,uint32_t dbTimeMs,uint32_t nStages,H4GM_FN_EVENT callback);//
DebouncedPin* Debounced(uint8_t p,uint8_t mode,H4GM_SENSE sense,uint32_t dbTimeMs,H4GM_FN_EVENT callback);//
DebouncedPin* DebouncedThing(uint8_t p,uint8_t mode,H4GM_SENSE sense,uint32_t dbTimeMs,H4P_BinaryThing* btp);//
Expand Down
17 changes: 9 additions & 8 deletions docs/things.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,14 @@ Your app can contain exactly one of these

And as many GPIO input connectors as you need, to make your app do whatever it needs to do

* DebouncedThing
* EncoderThing
* LatchingThing
* PolledThing
* RawThing
* RetriggeringThing
* [H4P_ThreeFunctionButton](h43fnb.md)
* AnalogThresholdThing [Example Code](../examples/H4GM_AnalogThresholdThing/H4GM_AnalogThresholdThing.ino)
* DebouncedThing [Example Code](../examples/H4GM_DebouncedThing/H4GM_DebouncedThing.ino)
* EncoderThing [Example Code](../examples/H4GM_EncoderThing/H4GM_EncoderThing.ino)
* LatchingThing [Example Code](../examples/H4GM_LatchingThing/H4GM_LatchingThing.ino)
* PolledThing [Example Code](../examples/H4GM_PolledThing/H4GM_PolledThing.ino)
* RawThing [Example Code](../examples/H4GM_RawThing/H4GM_RawThing.ino)
* RetriggeringThing [Example Code](../examples/H4GM_RetriggeringThing/H4GM_RetriggeringThing.ino)
* [H4P_ThreeFunctionButton](h43fnb.md) [Example Code](../examples/H4P_SONOFF_Basic/H4P_SONOFF_Basic.ino)

---

Expand Down Expand Up @@ -197,6 +198,7 @@ void friendlyName(const string& name); // sets UPNP friendly name. Causes a rebo
You need to read the [H4P_GPIOManager](h4gm.md) documentation before using these
[Example Sketch - AnalogThresholdThing](../examples/H4GM_DebouncedThing/H4GM_DebouncedThing.ino)
[Example Sketch - DebouncedThing](../examples/H4GM_DebouncedThing/H4GM_DebouncedThing.ino)
[Example Sketch - EncoderThing](../examples/H4GM_EncoderThing/H4GM_EncoderThing.ino)
[Example Sketch - LatchingThing](../examples/H4GM_LatchingThing/H4GM_LatchingThing.ino)
Expand Down Expand Up @@ -262,7 +264,6 @@ The integer number of repeat UDP messages sent on each occasion to prevent packe
---
(c) 2020 Phil Bowles h4plugins@gmail.com
* [Youtube channel (instructional videos)](https://www.youtube.com/channel/UCYi-Ko76_3p9hBUtleZRY6g)
Expand Down
64 changes: 64 additions & 0 deletions examples/H4GM_AnalogThreshold/H4GM_AnalogThreshold.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include<H4Plugins.h>
H4_USE_PLUGINS
/*
My major testing devices were nodeMCU which has builtin button on GPIO0 which is ACTIVE_LOW
and STM32NUCLEO-F429ZI whuch has a user button that is ACTIVE_HIGH
You will probably need to adjust these values for you own device
*/
#ifdef ARDUINO_ARCH_STM32
#define UB_ACTIVE ACTIVE_HIGH
#define UL_ACTIVE ACTIVE_HIGH
#else
#define USER_BTN 0
#define UB_ACTIVE ACTIVE_LOW
#define UL_ACTIVE ACTIVE_LOW
#endif
/*
ALL GPIO strategies are derived from H4GPIOPin: the following members are available
inside ALL GPIO pin callbacks, once you have a valid pointer for the pin type using
H4GM_PIN( type ) with specific underlying type Raw needs H4GM_PIN(Raw);
uint8_t pin=0; // GPIO hardware pin number
uint8_t gpioType=0; // INPUT, INPUT_PULLUP, OUTPUT etc
H4GM_STYLE style; // Strategy: Raw, debounced, retriggering etc
uint8_t sense=0; // active HIGH or LOW
unsigned long Tevt=0; // uS time of last event
int state=0; // 32 wide as it holds analog value as well as digital 0/1
// and not uint because encoder returns -1 or +1
uint32_t delta=0; // uS since last change
uint32_t rate=0; // instantaenous rate cps
uint32_t Rpeak=0; // peak rate
uint32_t cps=0; // sigma changes/sec (used internally, frequently re-set)
uint32_t cMax=UINT_MAX; // max permitted cps (see "throttling");
uint32_t nEvents=UINT_MAX; // sigma "Events" (meaning depends on inheriting strategy)
Additional members for AnalogThreshold:
limit the threshold value: below this figure = 0, above it = 1
AnalogThreshold has its state checked periodically, usually with a large value, e.g. minutes. It is used
when you do *not* want to react quickly. A good example is a light sensor at dusk: you want lights
to come on when it is "dark". As the light fades the sensor will "flutter" rapidly for quite a long
time before settling to its "dark" value. Only *then* do you want to switch the lights.
Each time it is polled, it will compare the raw analog value with limit and return 1 ig greater, else 0
analog value.
*/

H4 h4(115200); //auto-start Serial @ 115200, Q size=20
H4P_GPIOManager h4gm;

#define U_POLL_FREQ 5000
#define U_LIMIT 100

void h4setup() { // H4 constructor starts Serial
Serial.println("H4P_GPIOManager AnalogThreshold Example v"H4P_VERSION);

h4gm.AnalogThreshold(A0,U_POLL_FREQ,U_LIMIT,[](H4GPIOPin* ptr){
H4GM_PIN(AnalogThreshold); // Create the correct pointer type in 'pin'
Serial.print("T=");Serial.print(millis());
Serial.print(" AnalogThreshold ");Serial.print(pin->pin);
Serial.print(" AnalogThreshold IS ");Serial.println(pin->logicalRead());
});
}
15 changes: 15 additions & 0 deletions examples/H4GM_AnalogThresholdThing/H4GM_AnalogThresholdThing.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include<H4Plugins.h>
H4_USE_PLUGINS

#define F_POLL 5000

H4 h4(115200);
H4P_SerialCmd h4sc;
H4P_GPIOManager h4gm;

H4P_BinarySwitch h4onof(LED_BUILTIN,ACTIVE_LOW,OFF);

void h4setup(){
h4gm.AnalogThresholdThing(LIGHT,F_POLL,100,H4GM_GREATER,&h4onof); // On if A0 > 100
//h4gm.AnalogThresholdThing(LIGHT,F_POLL,100,H4GM_LESS,&h4onof); // On if A0 < 100
}
9 changes: 4 additions & 5 deletions examples/H4GM_Polled/H4GM_Polled.ino
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
#include<H4Plugins.h>
H4_USE_PLUGINS

H4 h4(115200,20); //auto-start Serial @ 115200, Q size=20

H4P_GPIOManager h4gm;
H4P_FlasherController h4fc;
/*
My major testing devices were nodeMCU which has builtin button on GPIO0 which is ACTIVE_LOW
and STM32NUCLEO-F429ZI whuch has a user button that is ACTIVE_HIGH
Expand Down Expand Up @@ -50,6 +45,10 @@ You will probably need to adjust these values for you own device
It can be used for both digital and analog values: when isAnalog == true; 'state' will contain raw
analog value.
*/

H4 h4(115200); //auto-start Serial @ 115200, Q size=20
H4P_GPIOManager h4gm;

#define U_POLL_FREQ 5000

void h4setup() { // H4 constructor starts Serial
Expand Down
2 changes: 1 addition & 1 deletion examples/H4GM_PolledThing/H4GM_PolledThing.ino
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,5 @@ void h4setup() { // H4 constructor starts Serial
Serial.println("H4P_GPIOManager Polled Example v"H4P_VERSION);
Serial.print("GPIO ");Serial.print(USER_BTN);Serial.print(" ACTIVE ");Serial.println(UB_ACTIVE ? "HIGH":"LOW");

h4gm.PolledThing(USER_BTN,INPUT,UB_ACTIVE,U_POLL_FREQ,true,&h4bt);
h4gm.PolledThing(USER_BTN,INPUT,UB_ACTIVE,U_POLL_FREQ,false,&h4bt);
}
31 changes: 31 additions & 0 deletions examples/youtube/SoundAndMotion/SoundAndMotion.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include<H4Plugins.h>
H4_USE_PLUGINS

#define LED_RED D6
#define LED_YELLOW D7
#define LED_GREEN D8

#define MOTION D1
#define LIGHT A0

#define F_POLL 5000

H4 h4(115200);
H4P_SerialCmd h4sc;
H4P_GPIOManager h4gm;
//H4P_WiFi h4wifi("XXXXXXXX","XXXXXXXX","h4plugins");
//H4P_MQTT h4mqtt("192.168.1.4",1883);
//H4P_AsyncWebServer h4asws("admin","admin");
//H4P_UPNPSwitch h4upnp("Demo Switch",RELAY_BUILTIN,ACTIVE_HIGH,OFF);
H4P_BinarySwitch h4onof(LED_RED,ACTIVE_HIGH,OFF);
H4P_FlasherController h4fc;
H4P_ThreeFunctionButton h43fb(&h4onof,15,BUTTON_BUILTIN,INPUT,ACTIVE_LOW,LED_BUILTIN,ACTIVE_LOW);

void h4setup(){
h4gm.RetriggeringThing(MOTION,INPUT,ACTIVE_HIGH,10000,&h4onof); // 10sec motion timeout
h4gm.Polled(LIGHT,INPUT,ACTIVE_HIGH,F_POLL,true,[](H4GPIOPin* ptr){
H4GM_PIN(Polled);
Serial.printf("POLLED = %d\n",pin->state);
h4onof.turn(pin->state < 60 ? 1:0);
}); // door alarm
}
9 changes: 6 additions & 3 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ EncoderAuto KEYWORD2
Filtered KEYWORD2
Latching KEYWORD2
logEvent KEYWORD2
logicalRead KEYWORD2
logicalWrite KEYWORD2
Latching KEYWORD2
Multistage KEYWORD2
Expand Down Expand Up @@ -113,7 +112,8 @@ exclude KEYWORD2
friendlyName KEYWORD2
host KEYWORD2
showSPIFFS KEYWORD2

AnalogThreshold KEYWORD2
AnalogThresholdThing KEYWORD2
DebouncedThing KEYWORD2
EncoderThing KEYWORD2
LatchingThing KEYWORD2
Expand All @@ -134,4 +134,7 @@ H4_CMD_NAME_UNKNOWN LITERAL1
H4_CMD_PAYLOAD_FORMAT LITERAL1
H4_CMD_PROHIBITED LITERAL1

H4P_FN_PSCHANGE LITERAL1
H4P_FN_PSCHANGE LITERAL1
H4GM_COMPARE LITERAL1
H4GM_LESS LITERAL1
H4GM_GREATER LITERAL1
Loading

0 comments on commit 814494c

Please sign in to comment.