mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-28 04:07:47 +00:00
Compare commits
83
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e457fe7597 | ||
|
|
dcd409e9d9 | ||
|
|
c227c13ba2 | ||
|
|
c64566ce49 | ||
|
|
a9366c8f23 | ||
|
|
bbf470c61d | ||
|
|
1c1211c4f3 | ||
|
|
7da0bc4a44 | ||
|
|
91a0c51ff8 | ||
|
|
0aa523a329 | ||
|
|
cac7275eb9 | ||
|
|
109eaf7d25 | ||
|
|
9ba15f2c19 | ||
|
|
1c07d787c5 | ||
|
|
b7ae2ea5fe | ||
|
|
b75bb204e3 | ||
|
|
bfc8006205 | ||
|
|
aab2e4a442 | ||
|
|
abfdfe014e | ||
|
|
f82040d2ef | ||
|
|
56f2cf3121 | ||
|
|
6349f07d1a | ||
|
|
1b44559d3e | ||
|
|
a151e60755 | ||
|
|
ce11c84e74 | ||
|
|
9808bf86c4 | ||
|
|
cfae636e55 | ||
|
|
ebaaf50df6 | ||
|
|
5c0be9e89f | ||
|
|
36468663f7 | ||
|
|
fba32608ee | ||
|
|
06848e50c3 | ||
|
|
879d0d4916 | ||
|
|
d083a58cd7 | ||
|
|
b1e9ff9fdc | ||
|
|
304280f415 | ||
|
|
2c8ca1421f | ||
|
|
3ce0fb9f75 | ||
|
|
8a71d2abd6 | ||
|
|
1b174f4eac | ||
|
|
f1d18c7b41 | ||
|
|
204d4607ba | ||
|
|
51f7ce0cb6 | ||
|
|
8f73deb133 | ||
|
|
1d4147309c | ||
|
|
a68e4c1456 | ||
|
|
2ee51363dd | ||
|
|
172eb37b5b | ||
|
|
68e1d8ea69 | ||
|
|
ac8e8db0e7 | ||
|
|
d72bf9b76c | ||
|
|
6d3f535d16 | ||
|
|
0709763f3a | ||
|
|
538d843643 | ||
|
|
2339ee928c | ||
|
|
9550b951d5 | ||
|
|
0491af8a2f | ||
|
|
806a2757b2 | ||
|
|
3931b71d00 | ||
|
|
af0c3d5f62 | ||
|
|
c7a6ca4555 | ||
|
|
4a01e2eb49 | ||
|
|
d6ff20b35d | ||
|
|
6b04539571 | ||
|
|
9380ec13dc | ||
|
|
86cf00759f | ||
|
|
0eb5f55d63 | ||
|
|
f27d2aa7eb | ||
|
|
2d3285aaaf | ||
|
|
765c56ccef | ||
|
|
02255180e9 | ||
|
|
886958d479 | ||
|
|
84cbc19f38 | ||
|
|
178ec9dfa9 | ||
|
|
e774ef5751 | ||
|
|
5d3f8bf073 | ||
|
|
dd88db1913 | ||
|
|
aab00567fc | ||
|
|
21cb6135dd | ||
|
|
07948c87aa | ||
|
|
4543a10739 | ||
|
|
daecf2017e | ||
|
|
37122bc619 |
@@ -1,18 +1,42 @@
|
||||
**NOTE: This is not a support forum! For questions and support go here: https://www.letscontrolit.com/forum/viewforum.php?f=1**
|
||||
<!--- NOTE: This is not a support forum! For questions and support go here: --->
|
||||
<!--- https://www.letscontrolit.com/forum/viewforum.php?f=1 --->
|
||||
<!--- Remove topics that are not applicable to your feature request of issue --->
|
||||
<!--- Remember to have a "to the point" TITLE --->
|
||||
|
||||
### Steps to reproduce
|
||||
How can we trigger this problem?
|
||||
|
||||
Does the problem persists after powering off and on? (just resetting isn't enough sometimes)
|
||||
### Summarize of the problem/feature request
|
||||
<!--- Describe the problem or feature request --->
|
||||
YOUR TEXT GOES HERE
|
||||
|
||||
### Expected behavior
|
||||
Tell us what should happen?
|
||||
<!--- Tell us what should happen? --->
|
||||
YOUR TEXT GOES HERE
|
||||
|
||||
### Actual behavior
|
||||
Tell us what happens instead?
|
||||
<!--- Tell us what happens instead? --->
|
||||
YOUR TEXT GOES HERE
|
||||
|
||||
### Steps to reproduce
|
||||
<!--- How can we trigger this problem? --->
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
<!--- Does the problem persists after powering off and on? (just resetting isn't enough sometimes) --->
|
||||
<!--- Please document if you have restarted the unit and if the problem is then gone etc. etc. --->
|
||||
### System configuration
|
||||
|
||||
<!--- Please add as much information and screenshots as possible --->
|
||||
Hardware:
|
||||
|
||||
Software or git version:
|
||||
<!--- You should also provide links to hardware pages etc where we can find more info --->
|
||||
ESP Easy version:
|
||||
|
||||
<!--- In order to have a better readablity of your issue then you should place screenshots here --->
|
||||
<!--- Simply drag and drop them onto this template, move the text string below the "ESP Easy settings/screenshots" topic --->
|
||||
ESP Easy settings/screenshots:
|
||||
|
||||
### Rules or log data
|
||||
<!--- place your code/rules between the two ``` rows --->
|
||||
<!--- remove if not applicable! --->
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
Vendored
+134
@@ -1,3 +1,137 @@
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180415 (since mega-20180414)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Sun Apr 15 04:00:08 CEST 2018
|
||||
|
||||
Gijs Noorlander (1):
|
||||
Added C013
|
||||
|
||||
Grovkillen (6):
|
||||
Made checkmarks CSS
|
||||
Fixed missed update.
|
||||
Added column width for separator...
|
||||
Updated some more stuff
|
||||
Made addFormSeparator function a lot cleaner
|
||||
Bumped delay timer for MQTT pub 10mSec
|
||||
|
||||
Nuno Sousa (1):
|
||||
Replace ultrasonic plugin with NewPing lib
|
||||
|
||||
Susis Strolch (4):
|
||||
add missing USES_XXX to _C*.ino, _N*.ino
|
||||
system variables %sysheap%, %syssec_d
|
||||
ignore power-on reset value (85.0 °C)
|
||||
DS_readTemp: handle power-on reset value
|
||||
|
||||
TD-er (4):
|
||||
[WebServer] Cleanup of all functions appending to a big string
|
||||
[PR #1247 ] Merged PR into the refactoring of Webserver
|
||||
[PR #1248] Fixed textarea sizes
|
||||
[Merge] Easier to merge, rebased on Mega branch.
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180414 (since mega-20180413)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Sat Apr 14 04:00:08 CEST 2018
|
||||
|
||||
GHolli (3):
|
||||
Update _P049_MHZ19.ino
|
||||
Change comma to semicolon
|
||||
Downstream updates (#1)
|
||||
|
||||
Gerald (1):
|
||||
Update _P049_MHZ19.ino
|
||||
|
||||
Grovkillen (4):
|
||||
Added RSSI, BSSID, Channel to WifiScan/Setup
|
||||
Removed the serial print "done."
|
||||
Added better(?) format for tables
|
||||
Fixed main page!
|
||||
|
||||
Holli (2):
|
||||
It seems the offsets [3]..[4] for the detection range setting (command byte 0x99) are wrong in the latest online data sheet: http://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19b-co2-ver1_0.pdf According to the MH-Z19B data sheet version 1.2, valid from: 2017.03.22 (received 2018-03-07), the offset should be [6]..[7] instead. Fixing the implementation accordingly.
|
||||
Disable detection range commands by default.
|
||||
|
||||
Plebs (5):
|
||||
Fixes for #1208 and partial #1196
|
||||
modified float() call
|
||||
new #formats
|
||||
added more formats
|
||||
Added #I
|
||||
|
||||
TD-er (1):
|
||||
[issue #1239] %bssid% and %wi_ch% added as variables
|
||||
|
||||
clumsy-stefan (1):
|
||||
_P015_TSL2561 added Broadband and IR Values
|
||||
|
||||
linuxnico (1):
|
||||
add ds1822 definition to ds_read_temp function
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180413 (since mega-20180412)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Fri Apr 13 04:00:09 CEST 2018
|
||||
|
||||
TD-er (1):
|
||||
[wifi] Event based wifi, fix set AP and crash on start
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180412 (since mega-20180410)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Thu Apr 12 04:00:14 CEST 2018
|
||||
|
||||
Gijs Noorlander (1):
|
||||
[MQTT] Process MQTT loop on publish
|
||||
|
||||
TD-er (7):
|
||||
[issue #1215] Cannot login to accesspoint on new install
|
||||
[issue #1215] Cannot login to accesspoint on new install
|
||||
[Wifi] Use statemachine to move between Wifi states
|
||||
[WiFi] Event based wifi, now AP mode works
|
||||
[wifi] Make it work for ESP32 again
|
||||
[wifi] Fix wifi AP setup mode for ESP32.
|
||||
[wifi] Event based wifi, improve scan information.
|
||||
|
||||
flexiti (1):
|
||||
ESP CPU speed and ID
|
||||
|
||||
mvdbro (1):
|
||||
Reboot/Reset pin, build 20101 patch
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180410 (since mega-20180409)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Tue Apr 10 04:00:21 CEST 2018
|
||||
|
||||
Grovkillen (5):
|
||||
Added comments that will not show up on issues
|
||||
Update issue_template.md
|
||||
Update issue_template.md
|
||||
Update issue_template.md
|
||||
Update issue_template.md
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180409 (since mega-20180407)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Mon Apr 9 04:00:13 CEST 2018
|
||||
|
||||
mvdbro (2):
|
||||
Factory Reset (not enabled yet)
|
||||
Both reset/factoryreset option
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180407 (since mega-20180405)
|
||||
-------------------------------------------------
|
||||
|
||||
Executable
+362
@@ -0,0 +1,362 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Created by Tim Eckel - teckel@leethost.com
|
||||
// Copyright 2016 License: GNU GPL v3 http://www.gnu.org/licenses/gpl.html
|
||||
//
|
||||
// See "NewPing.h" for purpose, syntax, version history, links, and more.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#include "NewPing.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// NewPing constructor
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
NewPing::NewPing(uint8_t trigger_pin, uint8_t echo_pin, unsigned int max_cm_distance) {
|
||||
#if DO_BITWISE == true
|
||||
_triggerBit = digitalPinToBitMask(trigger_pin); // Get the port register bitmask for the trigger pin.
|
||||
_echoBit = digitalPinToBitMask(echo_pin); // Get the port register bitmask for the echo pin.
|
||||
|
||||
_triggerOutput = portOutputRegister(digitalPinToPort(trigger_pin)); // Get the output port register for the trigger pin.
|
||||
_echoInput = portInputRegister(digitalPinToPort(echo_pin)); // Get the input port register for the echo pin.
|
||||
|
||||
_triggerMode = (uint8_t *) portModeRegister(digitalPinToPort(trigger_pin)); // Get the port mode register for the trigger pin.
|
||||
#else
|
||||
_triggerPin = trigger_pin;
|
||||
_echoPin = echo_pin;
|
||||
#endif
|
||||
|
||||
set_max_distance(max_cm_distance); // Call function to set the max sensor distance.
|
||||
|
||||
#if (defined (__arm__) && defined (TEENSYDUINO)) || DO_BITWISE != true
|
||||
pinMode(echo_pin, INPUT); // Set echo pin to input (on Teensy 3.x (ARM), pins default to disabled, at least one pinMode() is needed for GPIO mode).
|
||||
pinMode(trigger_pin, OUTPUT); // Set trigger pin to output (on Teensy 3.x (ARM), pins default to disabled, at least one pinMode() is needed for GPIO mode).
|
||||
#endif
|
||||
|
||||
#if defined (ARDUINO_AVR_YUN)
|
||||
pinMode(echo_pin, INPUT); // Set echo pin to input for the Arduino Yun, not sure why it doesn't default this way.
|
||||
#endif
|
||||
|
||||
#if ONE_PIN_ENABLED != true && DO_BITWISE == true
|
||||
*_triggerMode |= _triggerBit; // Set trigger pin to output.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Standard ping methods
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
unsigned int NewPing::ping(unsigned int max_cm_distance) {
|
||||
if (max_cm_distance > 0) set_max_distance(max_cm_distance); // Call function to set a new max sensor distance.
|
||||
|
||||
if (!ping_trigger()) return NO_ECHO; // Trigger a ping, if it returns false, return NO_ECHO to the calling function.
|
||||
|
||||
#if URM37_ENABLED == true
|
||||
#if DO_BITWISE == true
|
||||
while (!(*_echoInput & _echoBit)) // Wait for the ping echo.
|
||||
#else
|
||||
while (!digitalRead(_echoPin)) // Wait for the ping echo.
|
||||
#endif
|
||||
if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
|
||||
#else
|
||||
#if DO_BITWISE == true
|
||||
while (*_echoInput & _echoBit) // Wait for the ping echo.
|
||||
#else
|
||||
while (digitalRead(_echoPin)) // Wait for the ping echo.
|
||||
#endif
|
||||
if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
|
||||
#endif
|
||||
|
||||
return (micros() - (_max_time - _maxEchoTime) - PING_OVERHEAD); // Calculate ping time, include overhead.
|
||||
}
|
||||
|
||||
|
||||
unsigned long NewPing::ping_cm(unsigned int max_cm_distance) {
|
||||
unsigned long echoTime = NewPing::ping(max_cm_distance); // Calls the ping method and returns with the ping echo distance in uS.
|
||||
#if ROUNDING_ENABLED == false
|
||||
return (echoTime / US_ROUNDTRIP_CM); // Call the ping method and returns the distance in centimeters (no rounding).
|
||||
#else
|
||||
return NewPingConvert(echoTime, US_ROUNDTRIP_CM); // Convert uS to centimeters.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
unsigned long NewPing::ping_in(unsigned int max_cm_distance) {
|
||||
unsigned long echoTime = NewPing::ping(max_cm_distance); // Calls the ping method and returns with the ping echo distance in uS.
|
||||
#if ROUNDING_ENABLED == false
|
||||
return (echoTime / US_ROUNDTRIP_IN); // Call the ping method and returns the distance in inches (no rounding).
|
||||
#else
|
||||
return NewPingConvert(echoTime, US_ROUNDTRIP_IN); // Convert uS to inches.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
unsigned long NewPing::ping_median(uint8_t it, unsigned int max_cm_distance) {
|
||||
unsigned int uS[it], last;
|
||||
uint8_t j, i = 0;
|
||||
unsigned long t;
|
||||
uS[0] = NO_ECHO;
|
||||
|
||||
while (i < it) {
|
||||
t = micros(); // Start ping timestamp.
|
||||
last = ping(max_cm_distance); // Send ping.
|
||||
|
||||
if (last != NO_ECHO) { // Ping in range, include as part of median.
|
||||
if (i > 0) { // Don't start sort till second ping.
|
||||
for (j = i; j > 0 && uS[j - 1] < last; j--) // Insertion sort loop.
|
||||
uS[j] = uS[j - 1]; // Shift ping array to correct position for sort insertion.
|
||||
} else j = 0; // First ping is sort starting point.
|
||||
uS[j] = last; // Add last ping to array in sorted position.
|
||||
i++; // Move to next ping.
|
||||
} else it--; // Ping out of range, skip and don't include as part of median.
|
||||
|
||||
if (i < it && micros() - t < PING_MEDIAN_DELAY)
|
||||
delay((PING_MEDIAN_DELAY + t - micros()) / 1000); // Millisecond delay between pings.
|
||||
|
||||
}
|
||||
return (uS[it >> 1]); // Return the ping distance median.
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Standard and timer interrupt ping method support functions (not called directly)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
boolean NewPing::ping_trigger() {
|
||||
#if DO_BITWISE == true
|
||||
#if ONE_PIN_ENABLED == true
|
||||
*_triggerMode |= _triggerBit; // Set trigger pin to output.
|
||||
#endif
|
||||
|
||||
*_triggerOutput &= ~_triggerBit; // Set the trigger pin low, should already be low, but this will make sure it is.
|
||||
delayMicroseconds(4); // Wait for pin to go low.
|
||||
*_triggerOutput |= _triggerBit; // Set trigger pin high, this tells the sensor to send out a ping.
|
||||
delayMicroseconds(10); // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS.
|
||||
*_triggerOutput &= ~_triggerBit; // Set trigger pin back to low.
|
||||
|
||||
#if ONE_PIN_ENABLED == true
|
||||
*_triggerMode &= ~_triggerBit; // Set trigger pin to input (when using one Arduino pin, this is technically setting the echo pin to input as both are tied to the same Arduino pin).
|
||||
#endif
|
||||
|
||||
#if URM37_ENABLED == true
|
||||
if (!(*_echoInput & _echoBit)) return false; // Previous ping hasn't finished, abort.
|
||||
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
|
||||
while (*_echoInput & _echoBit) // Wait for ping to start.
|
||||
if (micros() > _max_time) return false; // Took too long to start, abort.
|
||||
#else
|
||||
if (*_echoInput & _echoBit) return false; // Previous ping hasn't finished, abort.
|
||||
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
|
||||
while (!(*_echoInput & _echoBit)) // Wait for ping to start.
|
||||
if (micros() > _max_time) return false; // Took too long to start, abort.
|
||||
#endif
|
||||
#else
|
||||
#if ONE_PIN_ENABLED == true
|
||||
pinMode(_triggerPin, OUTPUT); // Set trigger pin to output.
|
||||
#endif
|
||||
|
||||
digitalWrite(_triggerPin, LOW); // Set the trigger pin low, should already be low, but this will make sure it is.
|
||||
delayMicroseconds(4); // Wait for pin to go low.
|
||||
digitalWrite(_triggerPin, HIGH); // Set trigger pin high, this tells the sensor to send out a ping.
|
||||
delayMicroseconds(10); // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS.
|
||||
digitalWrite(_triggerPin, LOW); // Set trigger pin back to low.
|
||||
|
||||
#if ONE_PIN_ENABLED == true
|
||||
pinMode(_triggerPin, INPUT); // Set trigger pin to input (when using one Arduino pin, this is technically setting the echo pin to input as both are tied to the same Arduino pin).
|
||||
#endif
|
||||
|
||||
#if URM37_ENABLED == true
|
||||
if (!digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort.
|
||||
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
|
||||
while (digitalRead(_echoPin)) // Wait for ping to start.
|
||||
if (micros() > _max_time) return false; // Took too long to start, abort.
|
||||
#else
|
||||
if (digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort.
|
||||
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
|
||||
while (!digitalRead(_echoPin)) // Wait for ping to start.
|
||||
if (micros() > _max_time) return false; // Took too long to start, abort.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
_max_time = micros() + _maxEchoTime; // Ping started, set the time-out.
|
||||
return true; // Ping started successfully.
|
||||
}
|
||||
|
||||
|
||||
void NewPing::set_max_distance(unsigned int max_cm_distance) {
|
||||
#if ROUNDING_ENABLED == false
|
||||
_maxEchoTime = min(max_cm_distance + 1, (unsigned int) MAX_SENSOR_DISTANCE + 1) * US_ROUNDTRIP_CM; // Calculate the maximum distance in uS (no rounding).
|
||||
#else
|
||||
_maxEchoTime = min(max_cm_distance, (unsigned int) MAX_SENSOR_DISTANCE) * US_ROUNDTRIP_CM + (US_ROUNDTRIP_CM / 2); // Calculate the maximum distance in uS.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if TIMER_ENABLED == true && DO_BITWISE == true
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Timer interrupt ping methods (won't work with non-AVR, ATmega128 and all ATtiny microcontrollers)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void NewPing::ping_timer(void (*userFunc)(void), unsigned int max_cm_distance) {
|
||||
if (max_cm_distance > 0) set_max_distance(max_cm_distance); // Call function to set a new max sensor distance.
|
||||
|
||||
if (!ping_trigger()) return; // Trigger a ping, if it returns false, return without starting the echo timer.
|
||||
timer_us(ECHO_TIMER_FREQ, userFunc); // Set ping echo timer check every ECHO_TIMER_FREQ uS.
|
||||
}
|
||||
|
||||
|
||||
boolean NewPing::check_timer() {
|
||||
if (micros() > _max_time) { // Outside the time-out limit.
|
||||
timer_stop(); // Disable timer interrupt
|
||||
return false; // Cancel ping timer.
|
||||
}
|
||||
|
||||
#if URM37_ENABLED == false
|
||||
if (!(*_echoInput & _echoBit)) { // Ping echo received.
|
||||
#else
|
||||
if (*_echoInput & _echoBit) { // Ping echo received.
|
||||
#endif
|
||||
timer_stop(); // Disable timer interrupt
|
||||
ping_result = (micros() - (_max_time - _maxEchoTime) - PING_TIMER_OVERHEAD); // Calculate ping time including overhead.
|
||||
return true; // Return ping echo true.
|
||||
}
|
||||
|
||||
return false; // Return false because there's no ping echo yet.
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Timer2/Timer4 interrupt methods (can be used for non-ultrasonic needs)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Variables used for timer functions
|
||||
void (*intFunc)();
|
||||
void (*intFunc2)();
|
||||
unsigned long _ms_cnt_reset;
|
||||
volatile unsigned long _ms_cnt;
|
||||
#if defined(__arm__) && defined(TEENSYDUINO)
|
||||
IntervalTimer itimer;
|
||||
#endif
|
||||
|
||||
|
||||
void NewPing::timer_us(unsigned int frequency, void (*userFunc)(void)) {
|
||||
intFunc = userFunc; // User's function to call when there's a timer event.
|
||||
timer_setup(); // Configure the timer interrupt.
|
||||
|
||||
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
|
||||
OCR4C = min((frequency>>2) - 1, 255); // Every count is 4uS, so divide by 4 (bitwise shift right 2) subtract one, then make sure we don't go over 255 limit.
|
||||
TIMSK4 = (1<<TOIE4); // Enable Timer4 interrupt.
|
||||
#elif defined (__arm__) && defined (TEENSYDUINO) // Timer for Teensy 3.x
|
||||
itimer.begin(userFunc, frequency); // Really simple on the Teensy 3.x, calls userFunc every 'frequency' uS.
|
||||
#else
|
||||
OCR2A = min((frequency>>2) - 1, 255); // Every count is 4uS, so divide by 4 (bitwise shift right 2) subtract one, then make sure we don't go over 255 limit.
|
||||
TIMSK2 |= (1<<OCIE2A); // Enable Timer2 interrupt.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void NewPing::timer_ms(unsigned long frequency, void (*userFunc)(void)) {
|
||||
intFunc = NewPing::timer_ms_cntdwn; // Timer events are sent here once every ms till user's frequency is reached.
|
||||
intFunc2 = userFunc; // User's function to call when user's frequency is reached.
|
||||
_ms_cnt = _ms_cnt_reset = frequency; // Current ms counter and reset value.
|
||||
timer_setup(); // Configure the timer interrupt.
|
||||
|
||||
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
|
||||
OCR4C = 249; // Every count is 4uS, so 1ms = 250 counts - 1.
|
||||
TIMSK4 = (1<<TOIE4); // Enable Timer4 interrupt.
|
||||
#elif defined (__arm__) && defined (TEENSYDUINO) // Timer for Teensy 3.x
|
||||
itimer.begin(NewPing::timer_ms_cntdwn, 1000); // Set timer to 1ms (1000 uS).
|
||||
#else
|
||||
OCR2A = 249; // Every count is 4uS, so 1ms = 250 counts - 1.
|
||||
TIMSK2 |= (1<<OCIE2A); // Enable Timer2 interrupt.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void NewPing::timer_stop() { // Disable timer interrupt.
|
||||
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
|
||||
TIMSK4 = 0;
|
||||
#elif defined (__arm__) && defined (TEENSYDUINO) // Timer for Teensy 3.x
|
||||
itimer.end();
|
||||
#else
|
||||
TIMSK2 &= ~(1<<OCIE2A);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Timer2/Timer4 interrupt method support functions (not called directly)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void NewPing::timer_setup() {
|
||||
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
|
||||
timer_stop(); // Disable Timer4 interrupt.
|
||||
TCCR4A = TCCR4C = TCCR4D = TCCR4E = 0;
|
||||
TCCR4B = (1<<CS42) | (1<<CS41) | (1<<CS40) | (1<<PSR4); // Set Timer4 prescaler to 64 (4uS/count, 4uS-1020uS range).
|
||||
TIFR4 = (1<<TOV4);
|
||||
TCNT4 = 0; // Reset Timer4 counter.
|
||||
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega8535__) // Alternate timer commands for certain microcontrollers.
|
||||
timer_stop(); // Disable Timer2 interrupt.
|
||||
ASSR &= ~(1<<AS2); // Set clock, not pin.
|
||||
TCCR2 = (1<<WGM21 | 1<<CS22); // Set Timer2 to CTC mode, prescaler to 64 (4uS/count, 4uS-1020uS range).
|
||||
TCNT2 = 0; // Reset Timer2 counter.
|
||||
#elif defined (__arm__) && defined (TEENSYDUINO)
|
||||
timer_stop(); // Stop the timer.
|
||||
#else
|
||||
timer_stop(); // Disable Timer2 interrupt.
|
||||
ASSR &= ~(1<<AS2); // Set clock, not pin.
|
||||
TCCR2A = (1<<WGM21); // Set Timer2 to CTC mode.
|
||||
TCCR2B = (1<<CS22); // Set Timer2 prescaler to 64 (4uS/count, 4uS-1020uS range).
|
||||
TCNT2 = 0; // Reset Timer2 counter.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void NewPing::timer_ms_cntdwn() {
|
||||
if (!_ms_cnt--) { // Count down till we reach zero.
|
||||
intFunc2(); // Scheduled time reached, run the main timer event function.
|
||||
_ms_cnt = _ms_cnt_reset; // Reset the ms timer.
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
|
||||
ISR(TIMER4_OVF_vect) {
|
||||
intFunc(); // Call wrapped function.
|
||||
}
|
||||
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega8535__) // Alternate timer commands for certain microcontrollers.
|
||||
ISR(TIMER2_COMP_vect) {
|
||||
intFunc(); // Call wrapped function.
|
||||
}
|
||||
#elif defined (__arm__)
|
||||
// Do nothing...
|
||||
#else
|
||||
ISR(TIMER2_COMPA_vect) {
|
||||
intFunc(); // Call wrapped function.
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Conversion methods (rounds result to nearest cm or inch).
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
unsigned int NewPing::convert_cm(unsigned int echoTime) {
|
||||
#if ROUNDING_ENABLED == false
|
||||
return (echoTime / US_ROUNDTRIP_CM); // Convert uS to centimeters (no rounding).
|
||||
#else
|
||||
return NewPingConvert(echoTime, US_ROUNDTRIP_CM); // Convert uS to centimeters.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
unsigned int NewPing::convert_in(unsigned int echoTime) {
|
||||
#if ROUNDING_ENABLED == false
|
||||
return (echoTime / US_ROUNDTRIP_IN); // Convert uS to inches (no rounding).
|
||||
#else
|
||||
return NewPingConvert(echoTime, US_ROUNDTRIP_IN); // Convert uS to inches.
|
||||
#endif
|
||||
}
|
||||
Executable
+245
@@ -0,0 +1,245 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// NewPing Library - v1.8 - 07/30/2016
|
||||
//
|
||||
// AUTHOR/LICENSE:
|
||||
// Created by Tim Eckel - teckel@leethost.com
|
||||
// Copyright 2016 License: GNU GPL v3 http://www.gnu.org/licenses/gpl.html
|
||||
//
|
||||
// LINKS:
|
||||
// Project home: https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home
|
||||
// Blog: http://arduino.cc/forum/index.php/topic,106043.0.html
|
||||
//
|
||||
// DISCLAIMER:
|
||||
// This software is furnished "as is", without technical support, and with no
|
||||
// warranty, express or implied, as to its usefulness for any purpose.
|
||||
//
|
||||
// BACKGROUND:
|
||||
// When I first received an ultrasonic sensor I was not happy with how poorly
|
||||
// it worked. Quickly I realized the problem wasn't the sensor, it was the
|
||||
// available ping and ultrasonic libraries causing the problem. The NewPing
|
||||
// library totally fixes these problems, adds many new features, and breaths
|
||||
// new life into these very affordable distance sensors.
|
||||
//
|
||||
// FEATURES:
|
||||
// * Works with many different ultrasonic sensors: SR04, SRF05, SRF06, DYP-ME007, URM37 & Parallax PING))).
|
||||
// * Compatible with the entire Arduino line-up (and clones), Teensy family (including $19 96Mhz 32 bit Teensy 3.2) and non-AVR microcontrollers.
|
||||
// * Interface with all but the SRF06 sensor using only one Arduino pin.
|
||||
// * Doesn't lag for a full second if no ping/echo is received.
|
||||
// * Ping sensors consistently and reliably at up to 30 times per second.
|
||||
// * Timer interrupt method for event-driven sketches.
|
||||
// * Built-in digital filter method ping_median() for easy error correction.
|
||||
// * Uses port registers for a faster pin interface and smaller code size.
|
||||
// * Allows you to set a maximum distance where pings beyond that distance are read as no ping "clear".
|
||||
// * Ease of using multiple sensors (example sketch with 15 sensors).
|
||||
// * More accurate distance calculation (cm, inches & uS).
|
||||
// * Doesn't use pulseIn, which is slow and gives incorrect results with some ultrasonic sensor models.
|
||||
// * Actively developed with features being added and bugs/issues addressed.
|
||||
//
|
||||
// CONSTRUCTOR:
|
||||
// NewPing sonar(trigger_pin, echo_pin [, max_cm_distance])
|
||||
// trigger_pin & echo_pin - Arduino pins connected to sensor trigger and echo.
|
||||
// NOTE: To use the same Arduino pin for trigger and echo, specify the same pin for both values.
|
||||
// max_cm_distance - [Optional] Maximum distance you wish to sense. Default=500cm.
|
||||
//
|
||||
// METHODS:
|
||||
// sonar.ping([max_cm_distance]) - Send a ping and get the echo time (in microseconds) as a result. [max_cm_distance] allows you to optionally set a new max distance.
|
||||
// sonar.ping_in([max_cm_distance]) - Send a ping and get the distance in whole inches. [max_cm_distance] allows you to optionally set a new max distance.
|
||||
// sonar.ping_cm([max_cm_distance]) - Send a ping and get the distance in whole centimeters. [max_cm_distance] allows you to optionally set a new max distance.
|
||||
// sonar.ping_median(iterations [, max_cm_distance]) - Do multiple pings (default=5), discard out of range pings and return median in microseconds. [max_cm_distance] allows you to optionally set a new max distance.
|
||||
// NewPing::convert_in(echoTime) - Convert echoTime from microseconds to inches (rounds to nearest inch).
|
||||
// NewPing::convert_cm(echoTime) - Convert echoTime from microseconds to centimeters (rounds to nearest cm).
|
||||
// sonar.ping_timer(function [, max_cm_distance]) - Send a ping and call function to test if ping is complete. [max_cm_distance] allows you to optionally set a new max distance.
|
||||
// sonar.check_timer() - Check if ping has returned within the set distance limit.
|
||||
// NewPing::timer_us(frequency, function) - Call function every frequency microseconds.
|
||||
// NewPing::timer_ms(frequency, function) - Call function every frequency milliseconds.
|
||||
// NewPing::timer_stop() - Stop the timer.
|
||||
//
|
||||
// HISTORY:
|
||||
// 07/30/2016 v1.8 - Added support for non-AVR microcontrollers. For non-AVR
|
||||
// microcontrollers, advanced ping_timer() timer methods are disabled due to
|
||||
// inconsistencies or no support at all between platforms. However, standard
|
||||
// ping methods are all supported. Added new optional variable to ping(),
|
||||
// ping_in(), ping_cm(), ping_median(), and ping_timer() methods which allows
|
||||
// you to set a new maximum distance for each ping. Added support for the
|
||||
// ATmega16, ATmega32 and ATmega8535 microcontrollers. Changed convert_cm()
|
||||
// and convert_in() methods to static members. You can now call them without
|
||||
// an object. For example: cm = NewPing::convert_cm(distance);
|
||||
//
|
||||
// 09/29/2015 v1.7 - Removed support for the Arduino Due and Zero because
|
||||
// they're both 3.3 volt boards and are not 5 volt tolerant while the HC-SR04
|
||||
// is a 5 volt sensor. Also, the Due and Zero don't support pin manipulation
|
||||
// compatibility via port registers which can be done (see the Teensy 3.2).
|
||||
//
|
||||
// 06/17/2014 v1.6 - Corrected delay between pings when using ping_median()
|
||||
// method. Added support for the URM37 sensor (must change URM37_ENABLED from
|
||||
// false to true). Added support for Arduino microcontrollers like the $20
|
||||
// 32 bit ARM Cortex-M4 based Teensy 3.2. Added automatic support for the
|
||||
// Atmel ATtiny family of microcontrollers. Added timer support for the
|
||||
// ATmega8 microcontroller. Rounding disabled by default, reduces compiled
|
||||
// code size (can be turned on with ROUNDING_ENABLED switch). Added
|
||||
// TIMER_ENABLED switch to get around compile-time "__vector_7" errors when
|
||||
// using the Tone library, or you can use the toneAC, NewTone or
|
||||
// TimerFreeTone libraries: https://bitbucket.org/teckel12/arduino-toneac/
|
||||
// Other speed and compiled size optimizations.
|
||||
//
|
||||
// 08/15/2012 v1.5 - Added ping_median() method which does a user specified
|
||||
// number of pings (default=5) and returns the median ping in microseconds
|
||||
// (out of range pings ignored). This is a very effective digital filter.
|
||||
// Optimized for smaller compiled size (even smaller than sketches that
|
||||
// don't use a library).
|
||||
//
|
||||
// 07/14/2012 v1.4 - Added support for the Parallax PING)))� sensor. Interface
|
||||
// with all but the SRF06 sensor using only one Arduino pin. You can also
|
||||
// interface with the SRF06 using one pin if you install a 0.1uf capacitor
|
||||
// on the trigger and echo pins of the sensor then tie the trigger pin to
|
||||
// the Arduino pin (doesn't work with Teensy). To use the same Arduino pin
|
||||
// for trigger and echo, specify the same pin for both values. Various bug
|
||||
// fixes.
|
||||
//
|
||||
// 06/08/2012 v1.3 - Big feature addition, event-driven ping! Uses Timer2
|
||||
// interrupt, so be mindful of PWM or timing conflicts messing with Timer2
|
||||
// may cause (namely PWM on pins 3 & 11 on Arduino, PWM on pins 9 and 10 on
|
||||
// Mega, and Tone library). Simple to use timer interrupt functions you can
|
||||
// use in your sketches totally unrelated to ultrasonic sensors (don't use if
|
||||
// you're also using NewPing's ping_timer because both use Timer2 interrupts).
|
||||
// Loop counting ping method deleted in favor of timing ping method after
|
||||
// inconsistent results kept surfacing with the loop timing ping method.
|
||||
// Conversion to cm and inches now rounds to the nearest cm or inch. Code
|
||||
// optimized to save program space and fixed a couple minor bugs here and
|
||||
// there. Many new comments added as well as line spacing to group code
|
||||
// sections for better source readability.
|
||||
//
|
||||
// 05/25/2012 v1.2 - Lots of code clean-up thanks to Arduino Forum members.
|
||||
// Rebuilt the ping timing code from scratch, ditched the pulseIn code as it
|
||||
// doesn't give correct results (at least with ping sensors). The NewPing
|
||||
// library is now VERY accurate and the code was simplified as a bonus.
|
||||
// Smaller and faster code as well. Fixed some issues with very close ping
|
||||
// results when converting to inches. All functions now return 0 only when
|
||||
// there's no ping echo (out of range) and a positive value for a successful
|
||||
// ping. This can effectively be used to detect if something is out of range
|
||||
// or in-range and at what distance. Now compatible with Arduino 0023.
|
||||
//
|
||||
// 05/16/2012 v1.1 - Changed all I/O functions to use low-level port registers
|
||||
// for ultra-fast and lean code (saves from 174 to 394 bytes). Tested on both
|
||||
// the Arduino Uno and Teensy 2.0 but should work on all Arduino-based
|
||||
// platforms because it calls standard functions to retrieve port registers
|
||||
// and bit masks. Also made a couple minor fixes to defines.
|
||||
//
|
||||
// 05/15/2012 v1.0 - Initial release.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#ifndef NewPing_h
|
||||
#define NewPing_h
|
||||
|
||||
#if defined (ARDUINO) && ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <pins_arduino.h>
|
||||
#endif
|
||||
|
||||
#if defined (__AVR__)
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#endif
|
||||
|
||||
// Shouldn't need to change these values unless you have a specific need to do so.
|
||||
#define MAX_SENSOR_DISTANCE 500 // Maximum sensor distance can be as high as 500cm, no reason to wait for ping longer than sound takes to travel this distance and back. Default=500
|
||||
#define US_ROUNDTRIP_CM 57 // Microseconds (uS) it takes sound to travel round-trip 1cm (2cm total), uses integer to save compiled code space. Default=57
|
||||
#define US_ROUNDTRIP_IN 146 // Microseconds (uS) it takes sound to travel round-trip 1 inch (2 inches total), uses integer to save compiled code space. Defalult=146
|
||||
#define ONE_PIN_ENABLED true // Set to "false" to disable one pin mode which saves around 14-26 bytes of binary size. Default=true
|
||||
#define ROUNDING_ENABLED false // Set to "true" to enable distance rounding which also adds 64 bytes to binary size. Default=false
|
||||
#define URM37_ENABLED false // Set to "true" to enable support for the URM37 sensor in PWM mode. Default=false
|
||||
#define TIMER_ENABLED true // Set to "false" to disable the timer ISR (if getting "__vector_7" compile errors set this to false). Default=true
|
||||
|
||||
// Probably shouldn't change these values unless you really know what you're doing.
|
||||
#define NO_ECHO 0 // Value returned if there's no ping echo within the specified MAX_SENSOR_DISTANCE or max_cm_distance. Default=0
|
||||
#define MAX_SENSOR_DELAY 5800 // Maximum uS it takes for sensor to start the ping. Default=5800
|
||||
#define ECHO_TIMER_FREQ 24 // Frequency to check for a ping echo (every 24uS is about 0.4cm accuracy). Default=24
|
||||
#define PING_MEDIAN_DELAY 29000 // Microsecond delay between pings in the ping_median method. Default=29000
|
||||
#define PING_OVERHEAD 5 // Ping overhead in microseconds (uS). Default=5
|
||||
#define PING_TIMER_OVERHEAD 13 // Ping timer overhead in microseconds (uS). Default=13
|
||||
#if URM37_ENABLED == true
|
||||
#undef US_ROUNDTRIP_CM
|
||||
#undef US_ROUNDTRIP_IN
|
||||
#define US_ROUNDTRIP_CM 50 // Every 50uS PWM signal is low indicates 1cm distance. Default=50
|
||||
#define US_ROUNDTRIP_IN 127 // If 50uS is 1cm, 1 inch would be 127uS (50 x 2.54 = 127). Default=127
|
||||
#endif
|
||||
|
||||
// Conversion from uS to distance (round result to nearest cm or inch).
|
||||
#define NewPingConvert(echoTime, conversionFactor) (max(((unsigned int)echoTime + conversionFactor / 2) / conversionFactor, (echoTime ? 1 : 0)))
|
||||
|
||||
// Detect non-AVR microcontrollers (Teensy 3.x, Arduino DUE, etc.) and don't use port registers or timer interrupts as required.
|
||||
#if (defined (__arm__) && defined (TEENSYDUINO))
|
||||
#undef PING_OVERHEAD
|
||||
#define PING_OVERHEAD 1
|
||||
#undef PING_TIMER_OVERHEAD
|
||||
#define PING_TIMER_OVERHEAD 1
|
||||
#define DO_BITWISE true
|
||||
#elif !defined (__AVR__)
|
||||
#undef PING_OVERHEAD
|
||||
#define PING_OVERHEAD 1
|
||||
#undef PING_TIMER_OVERHEAD
|
||||
#define PING_TIMER_OVERHEAD 1
|
||||
#undef TIMER_ENABLED
|
||||
#define TIMER_ENABLED false
|
||||
#define DO_BITWISE false
|
||||
#else
|
||||
#define DO_BITWISE true
|
||||
#endif
|
||||
|
||||
// Disable the timer interrupts when using ATmega128 and all ATtiny microcontrollers.
|
||||
#if defined (__AVR_ATmega128__) || defined (__AVR_ATtiny24__) || defined (__AVR_ATtiny44__) || defined (__AVR_ATtiny84__) || defined (__AVR_ATtiny25__) || defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__) || defined (__AVR_ATtiny261__) || defined (__AVR_ATtiny461__) || defined (__AVR_ATtiny861__) || defined (__AVR_ATtiny43U__)
|
||||
#undef TIMER_ENABLED
|
||||
#define TIMER_ENABLED false
|
||||
#endif
|
||||
|
||||
// Define timers when using ATmega8, ATmega16, ATmega32 and ATmega8535 microcontrollers.
|
||||
#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega8535__)
|
||||
#define OCR2A OCR2
|
||||
#define TIMSK2 TIMSK
|
||||
#define OCIE2A OCIE2
|
||||
#endif
|
||||
|
||||
class NewPing {
|
||||
public:
|
||||
NewPing(uint8_t trigger_pin, uint8_t echo_pin, unsigned int max_cm_distance = MAX_SENSOR_DISTANCE);
|
||||
unsigned int ping(unsigned int max_cm_distance = 0);
|
||||
unsigned long ping_cm(unsigned int max_cm_distance = 0);
|
||||
unsigned long ping_in(unsigned int max_cm_distance = 0);
|
||||
unsigned long ping_median(uint8_t it = 5, unsigned int max_cm_distance = 0);
|
||||
static unsigned int convert_cm(unsigned int echoTime);
|
||||
static unsigned int convert_in(unsigned int echoTime);
|
||||
#if TIMER_ENABLED == true
|
||||
void ping_timer(void (*userFunc)(void), unsigned int max_cm_distance = 0);
|
||||
boolean check_timer();
|
||||
unsigned long ping_result;
|
||||
static void timer_us(unsigned int frequency, void (*userFunc)(void));
|
||||
static void timer_ms(unsigned long frequency, void (*userFunc)(void));
|
||||
static void timer_stop();
|
||||
#endif
|
||||
private:
|
||||
boolean ping_trigger();
|
||||
void set_max_distance(unsigned int max_cm_distance);
|
||||
#if TIMER_ENABLED == true
|
||||
boolean ping_trigger_timer(unsigned int trigger_delay);
|
||||
boolean ping_wait_timer();
|
||||
static void timer_setup();
|
||||
static void timer_ms_cntdwn();
|
||||
#endif
|
||||
#if DO_BITWISE == true
|
||||
uint8_t _triggerBit;
|
||||
uint8_t _echoBit;
|
||||
volatile uint8_t *_triggerOutput;
|
||||
volatile uint8_t *_echoInput;
|
||||
volatile uint8_t *_triggerMode;
|
||||
#else
|
||||
uint8_t _triggerPin;
|
||||
uint8_t _echoPin;
|
||||
#endif
|
||||
unsigned int _maxEchoTime;
|
||||
unsigned long _max_time;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// This example code was used to successfully communicate with 15 ultrasonic sensors. You can adjust
|
||||
// the number of sensors in your project by changing SONAR_NUM and the number of NewPing objects in the
|
||||
// "sonar" array. You also need to change the pins for each sensor for the NewPing objects. Each sensor
|
||||
// is pinged at 33ms intervals. So, one cycle of all sensors takes 495ms (33 * 15 = 495ms). The results
|
||||
// are sent to the "oneSensorCycle" function which currently just displays the distance data. Your project
|
||||
// would normally process the sensor results in this function (for example, decide if a robot needs to
|
||||
// turn and call the turn function). Keep in mind this example is event-driven. Your complete sketch needs
|
||||
// to be written so there's no "delay" commands and the loop() cycles at faster than a 33ms rate. If other
|
||||
// processes take longer than 33ms, you'll need to increase PING_INTERVAL so it doesn't get behind.
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <NewPing.h>
|
||||
|
||||
#define SONAR_NUM 15 // Number of sensors.
|
||||
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
|
||||
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
|
||||
|
||||
unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
|
||||
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
|
||||
uint8_t currentSensor = 0; // Keeps track of which sensor is active.
|
||||
|
||||
NewPing sonar[SONAR_NUM] = { // Sensor object array.
|
||||
NewPing(41, 42, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
|
||||
NewPing(43, 44, MAX_DISTANCE),
|
||||
NewPing(45, 20, MAX_DISTANCE),
|
||||
NewPing(21, 22, MAX_DISTANCE),
|
||||
NewPing(23, 24, MAX_DISTANCE),
|
||||
NewPing(25, 26, MAX_DISTANCE),
|
||||
NewPing(27, 28, MAX_DISTANCE),
|
||||
NewPing(29, 30, MAX_DISTANCE),
|
||||
NewPing(31, 32, MAX_DISTANCE),
|
||||
NewPing(34, 33, MAX_DISTANCE),
|
||||
NewPing(35, 36, MAX_DISTANCE),
|
||||
NewPing(37, 38, MAX_DISTANCE),
|
||||
NewPing(39, 40, MAX_DISTANCE),
|
||||
NewPing(50, 51, MAX_DISTANCE),
|
||||
NewPing(52, 53, MAX_DISTANCE)
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting.
|
||||
for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
|
||||
pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
|
||||
if (millis() >= pingTimer[i]) { // Is it this sensor's time to ping?
|
||||
pingTimer[i] += PING_INTERVAL * SONAR_NUM; // Set next time this sensor will be pinged.
|
||||
if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
|
||||
sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance).
|
||||
currentSensor = i; // Sensor being accessed.
|
||||
cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor.
|
||||
sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
|
||||
}
|
||||
}
|
||||
// Other code that *DOESN'T* analyze ping results can go here.
|
||||
}
|
||||
|
||||
void echoCheck() { // If ping received, set the sensor distance to array.
|
||||
if (sonar[currentSensor].check_timer())
|
||||
cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
|
||||
}
|
||||
|
||||
void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
|
||||
// The following code would be replaced with your code that does something with the ping results.
|
||||
for (uint8_t i = 0; i < SONAR_NUM; i++) {
|
||||
Serial.print(i);
|
||||
Serial.print("=");
|
||||
Serial.print(cm[i]);
|
||||
Serial.print("cm ");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// This example shows how to use NewPing's ping_timer method which uses the Timer2 interrupt to get the
|
||||
// ping time. The advantage of using this method over the standard ping method is that it permits a more
|
||||
// event-driven sketch which allows you to appear to do two things at once. An example would be to ping
|
||||
// an ultrasonic sensor for a possible collision while at the same time navigating. This allows a
|
||||
// properly developed sketch to multitask. Be aware that because the ping_timer method uses Timer2,
|
||||
// other features or libraries that also use Timer2 would be effected. For example, the PWM function on
|
||||
// pins 3 & 11 on Arduino Uno (pins 9 and 11 on Arduino Mega) and the Tone library. Note, only the PWM
|
||||
// functionality of the pins is lost (as they use Timer2 to do PWM), the pins are still available to use.
|
||||
// NOTE: For Teensy/Leonardo (ATmega32U4) the library uses Timer4 instead of Timer2.
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <NewPing.h>
|
||||
|
||||
#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on ping sensor.
|
||||
#define ECHO_PIN 11 // Arduino pin tied to echo pin on ping sensor.
|
||||
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
|
||||
|
||||
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
|
||||
|
||||
unsigned int pingSpeed = 50; // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
|
||||
unsigned long pingTimer; // Holds the next ping time.
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
|
||||
pingTimer = millis(); // Start now.
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distance pings.
|
||||
if (millis() >= pingTimer) { // pingSpeed milliseconds since last ping, do another ping.
|
||||
pingTimer += pingSpeed; // Set the next ping time.
|
||||
sonar.ping_timer(echoCheck); // Send out the ping, calls "echoCheck" function every 24uS where you can check the ping status.
|
||||
}
|
||||
// Do other stuff here, really. Think of it as multi-tasking.
|
||||
}
|
||||
|
||||
void echoCheck() { // Timer2 interrupt calls this function every 24uS where you can check the ping status.
|
||||
// Don't do anything here!
|
||||
if (sonar.check_timer()) { // This is how you check to see if the ping was received.
|
||||
// Here's where you can add code.
|
||||
Serial.print("Ping: ");
|
||||
Serial.print(sonar.ping_result / US_ROUNDTRIP_CM); // Ping returned, uS result in ping_result, convert to cm with US_ROUNDTRIP_CM.
|
||||
Serial.println("cm");
|
||||
}
|
||||
// Don't do anything here!
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Example NewPing library sketch that does a ping about 20 times per second.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#include <NewPing.h>
|
||||
|
||||
#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on the ultrasonic sensor.
|
||||
#define ECHO_PIN 11 // Arduino pin tied to echo pin on the ultrasonic sensor.
|
||||
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
|
||||
|
||||
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
|
||||
Serial.print("Ping: ");
|
||||
Serial.print(sonar.ping_cm()); // Send ping, get distance in cm and print result (0 = outside set distance range)
|
||||
Serial.println("cm");
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// While the NewPing library's primary goal is to interface with ultrasonic sensors, interfacing with
|
||||
// the Timer2 interrupt was a result of creating an interrupt-based ping method. Since these Timer2
|
||||
// interrupt methods were built, the library may as well provide the functionality to use these methods
|
||||
// in your sketches. This shows how simple it is (no ultrasonic sensor required). Keep in mind that
|
||||
// these methods use Timer2, as does NewPing's ping_timer method for using ultrasonic sensors. You
|
||||
// can't use ping_timer at the same time you're using timer_ms or timer_us as all use the same timer.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#include <NewPing.h>
|
||||
|
||||
#define LED_PIN 13 // Pin with LED attached.
|
||||
|
||||
void setup() {
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
NewPing::timer_ms(500, toggleLED); // Create a Timer2 interrupt that calls toggleLED in your sketch once every 500 milliseconds.
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Do anything here, the Timer2 interrupt will take care of the flashing LED without your intervention.
|
||||
}
|
||||
|
||||
void toggleLED() {
|
||||
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle the LED.
|
||||
}
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
###################################
|
||||
# Syntax Coloring Map For NewPing
|
||||
###################################
|
||||
|
||||
###################################
|
||||
# Datatypes (KEYWORD1)
|
||||
###################################
|
||||
|
||||
NewPing KEYWORD1
|
||||
|
||||
###################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
###################################
|
||||
|
||||
ping KEYWORD2
|
||||
ping_in KEYWORD2
|
||||
ping_cm KEYWORD2
|
||||
ping_median KEYWORD2
|
||||
ping_timer KEYWORD2
|
||||
check_timer KEYWORD2
|
||||
timer_us KEYWORD2
|
||||
timer_ms KEYWORD2
|
||||
timer_stop KEYWORD2
|
||||
convert_in KEYWORD2
|
||||
convert_cm KEYWORD2
|
||||
|
||||
###################################
|
||||
# Constants (LITERAL1)
|
||||
###################################
|
||||
+24
-11
@@ -39,6 +39,9 @@ platform = espressif8266@1.5.0
|
||||
[core_2_4_0]
|
||||
platform = espressif8266@1.6.0
|
||||
|
||||
[core_staged]
|
||||
platform = https://github.com/platformio/platform-espressif8266.git#feature/stage
|
||||
|
||||
[core_esp32]
|
||||
#platform = espressif32@0.12.0
|
||||
platform = https://github.com/platformio/platform-espressif32.git#feature/stage
|
||||
@@ -55,6 +58,16 @@ lib_ldf_mode = chain
|
||||
upload_speed = 460800
|
||||
framework = arduino
|
||||
board = esp12e
|
||||
platform = ${core_2_4_0.platform}
|
||||
|
||||
[normal]
|
||||
platform = ${common.platform}
|
||||
|
||||
# Testing and dev take too much memory for using 2.4.x core library.
|
||||
[testing]
|
||||
platform = ${core_2_3_0.platform}
|
||||
|
||||
[dev]
|
||||
platform = ${core_2_3_0.platform}
|
||||
|
||||
|
||||
@@ -156,7 +169,7 @@ build_flags = ${esp8266_4M.build_flags}
|
||||
|
||||
# TEST: 1024k version ----------------------------
|
||||
[env:test_ESP8266_1024]
|
||||
platform = ${common.platform}
|
||||
platform = ${testing.platform}
|
||||
lib_deps = ${common.lib_deps}
|
||||
lib_ignore = ${common.lib_ignore}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
@@ -168,7 +181,7 @@ build_flags = ${esp8266_1M.build_flags} -D PLUGIN_BUILD_TESTING
|
||||
|
||||
# TEST: 1024k for esp8285 ------------------------
|
||||
[env:test_ESP8285_1024]
|
||||
platform = ${common.platform}
|
||||
platform = ${testing.platform}
|
||||
lib_deps = ${common.lib_deps}
|
||||
lib_ignore = ${common.lib_ignore}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
@@ -180,7 +193,7 @@ build_flags = ${esp8285_1M.build_flags} -D PLUGIN_BUILD_TESTING
|
||||
|
||||
# TEST: 2048k version ----------------------------
|
||||
[env:test_WROOM02_2048]
|
||||
platform = ${common.platform}
|
||||
platform = ${testing.platform}
|
||||
lib_deps = ${common.lib_deps}
|
||||
lib_ignore = ${common.lib_ignore}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
@@ -192,7 +205,7 @@ build_flags = ${espWroom2M.build_flags} -D PLUGIN_BUILD_TESTING
|
||||
|
||||
# TEST: 4096k version ----------------------------
|
||||
[env:test_ESP8266_4096]
|
||||
platform = ${common.platform}
|
||||
platform = ${testing.platform}
|
||||
lib_deps = ${common.lib_deps}
|
||||
lib_ignore = ${common.lib_ignore}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
@@ -204,7 +217,7 @@ build_flags = ${esp8266_4M.build_flags} -D PLUGIN_BUILD_TESTING
|
||||
|
||||
# TEST: 4096k version + FEATURE_ADC_VCC ----------
|
||||
[env:test_ESP8266_4096_VCC]
|
||||
platform = ${common.platform}
|
||||
platform = ${testing.platform}
|
||||
lib_deps = ${common.lib_deps}
|
||||
lib_ignore = ${common.lib_ignore}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
@@ -222,7 +235,7 @@ build_flags = ${esp8266_4M.build_flags} -D PLUGIN_BUILD_TESTING -D FEATURE_
|
||||
|
||||
# DEV : 1024k version ----------------------------
|
||||
[env:dev_ESP8266_1024]
|
||||
platform = ${common.platform}
|
||||
platform = ${dev.platform}
|
||||
lib_deps = ${common.lib_deps}
|
||||
lib_ignore = ${common.lib_ignore}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
@@ -234,7 +247,7 @@ build_flags = ${esp8266_1M.build_flags} -D PLUGIN_BUILD_DEV
|
||||
|
||||
# DEV: 1024k for esp8285 -------------------------
|
||||
[env:dev_ESP8285_1024]
|
||||
platform = ${common.platform}
|
||||
platform = ${dev.platform}
|
||||
lib_deps = ${common.lib_deps}
|
||||
lib_ignore = ${common.lib_ignore}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
@@ -246,7 +259,7 @@ build_flags = ${esp8285_1M.build_flags} -D PLUGIN_BUILD_DEV
|
||||
|
||||
# DEV: 2048k version -----------------------------
|
||||
[env:dev_WROOM02_2048]
|
||||
platform = ${common.platform}
|
||||
platform = ${dev.platform}
|
||||
lib_deps = ${common.lib_deps}
|
||||
lib_ignore = ${common.lib_ignore}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
@@ -258,7 +271,7 @@ build_flags = ${espWroom2M.build_flags} -D PLUGIN_BUILD_DEV
|
||||
|
||||
# DEV : 4096k version ----------------------------
|
||||
[env:dev_ESP8266_4096]
|
||||
platform = ${common.platform}
|
||||
platform = ${dev.platform}
|
||||
lib_deps = ${common.lib_deps}
|
||||
lib_ignore = ${common.lib_ignore}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
@@ -276,7 +289,7 @@ build_flags = ${esp8266_4M.build_flags} -D PLUGIN_BUILD_DEV
|
||||
|
||||
# DEV+PUYA : 1024k version -----------------------
|
||||
[env:dev_ESP8266PUYA_1024]
|
||||
platform = ${common.platform}
|
||||
platform = ${dev.platform}
|
||||
lib_deps = ${common.lib_deps}
|
||||
lib_ignore = ${common.lib_ignore}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
@@ -288,7 +301,7 @@ build_flags = ${esp8266_1M.build_flags} -D PLUGIN_BUILD_DEV -D FLASH_QUIRK_
|
||||
|
||||
# DEV+PUYA : 1024k version + FEATURE_ADC_VCC -----
|
||||
[env:dev_ESP8266PUYA_1024_VCC]
|
||||
platform = ${common.platform}
|
||||
platform = ${dev.platform}
|
||||
lib_deps = ${common.lib_deps}
|
||||
lib_ignore = ${common.lib_ignore}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
|
||||
+3
-3
@@ -681,7 +681,7 @@ void ExecuteCommand(byte source, const char *Line)
|
||||
case cmd_WifiConnect:
|
||||
{
|
||||
success = true;
|
||||
WiFiConnectRelaxed();
|
||||
setWifiState(WifiTryConnect);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -694,7 +694,7 @@ void ExecuteCommand(byte source, const char *Line)
|
||||
|
||||
case cmd_WifiAPMode:
|
||||
{
|
||||
WifiAPMode(true);
|
||||
setWifiState(WifiEnableAP);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
@@ -746,7 +746,7 @@ void ExecuteCommand(byte source, const char *Line)
|
||||
{
|
||||
success = true;
|
||||
WiFi.persistent(true); // use SDK storage of SSID/WPA parameters
|
||||
WiFi.disconnect(); // this will store empty ssid/wpa into sdk storage
|
||||
WifiDisconnect(); // this will store empty ssid/wpa into sdk storage
|
||||
WiFi.persistent(false); // Do not use SDK storage of SSID/WPA parameters
|
||||
break;
|
||||
}
|
||||
|
||||
+5
-3
@@ -92,11 +92,11 @@ void callback(char* c_topic, byte* b_payload, unsigned int length) {
|
||||
String log;
|
||||
log=F("MQTT : Topic: ");
|
||||
log+=c_topic;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
|
||||
log=F("MQTT : Payload: ");
|
||||
log+=c_payload;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
|
||||
// sprintf_P(log, PSTR("%s%s"), "MQTT : Topic: ", c_topic);
|
||||
// addLog(LOG_LEVEL_DEBUG, log);
|
||||
@@ -227,8 +227,10 @@ void SendStatus(byte source, String status)
|
||||
|
||||
boolean MQTTpublish(int controller_idx, const char* topic, const char* payload, boolean retained)
|
||||
{
|
||||
if (MQTTclient.publish(topic, payload, retained))
|
||||
if (MQTTclient.publish(topic, payload, retained)) {
|
||||
timermqtt = millis() + 10; // Make sure the MQTT is being processed as soon as possible.
|
||||
return true;
|
||||
}
|
||||
addLog(LOG_LEVEL_DEBUG, F("MQTT : publish failed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
+39
-5
@@ -16,7 +16,8 @@
|
||||
#define DEFAULT_DELAY 60 // Sleep Delay in seconds
|
||||
|
||||
// --- Wifi AP Mode (when your Wifi Network is not reachable) ----------------------------------------
|
||||
#define DEFAULT_AP_IP 192,168,4,1 // Enter IP address (comma separated) for AP (config) mode
|
||||
#define DEFAULT_AP_IP 192,168,4,1 // Enter IP address (comma separated) for AP (config) mode
|
||||
#define DEFAULT_AP_SUBNET 255,255,255,0 // Enter IP address (comma separated) for AP (config) mode
|
||||
#define DEFAULT_AP_KEY "configesp" // Enter network WPA key for AP (config) mode
|
||||
|
||||
// --- Wifi Client Mode -----------------------------------------------------------------------------
|
||||
@@ -153,7 +154,7 @@
|
||||
#define VERSION 3 // Change in config.dat mapping needs a full reset
|
||||
#endif
|
||||
|
||||
#define BUILD 20100 // git version 2.1.0
|
||||
#define BUILD 20101 // git version 2.1.01
|
||||
#if defined(ESP8266)
|
||||
#define BUILD_NOTES " - Mega"
|
||||
#endif
|
||||
@@ -449,12 +450,15 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info);
|
||||
WiFiEventHandler stationConnectedHandler;
|
||||
WiFiEventHandler stationDisconnectedHandler;
|
||||
WiFiEventHandler stationGotIpHandler;
|
||||
WiFiEventHandler APModeStationConnectedHandler;
|
||||
WiFiEventHandler APModeStationDisconnectedHandler;
|
||||
#endif
|
||||
|
||||
// Setup DNS, only used if the ESP has no valid WiFi config
|
||||
const byte DNS_PORT = 53;
|
||||
IPAddress apIP(DEFAULT_AP_IP);
|
||||
DNSServer dnsServer;
|
||||
bool dnsServerActive = false;
|
||||
#ifdef FEATURE_MDNS
|
||||
MDNSResponder mdns;
|
||||
#endif
|
||||
@@ -571,6 +575,7 @@ struct SecurityStruct
|
||||
byte AllowedIPrangeLow[4]; // TD-er: Use these
|
||||
byte AllowedIPrangeHigh[4];
|
||||
byte IPblockLevel;
|
||||
|
||||
//its safe to extend this struct, up to 4096 bytes, default values in config are 0. Make sure crc is last
|
||||
uint8_t ProgmemMd5[16]; // crc of the binary that last saved the struct to file.
|
||||
uint8_t md5[16];
|
||||
@@ -692,6 +697,9 @@ struct SettingsStruct
|
||||
boolean ArduinoOTAEnable;
|
||||
uint16_t DST_Start;
|
||||
uint16_t DST_End;
|
||||
boolean UseRTOSMultitasking;
|
||||
int8_t Pin_Reset;
|
||||
|
||||
|
||||
//its safe to extend this struct, up to several bytes, default values in config are 0
|
||||
//look in misc.ino how config.dat is used because also other stuff is stored in it at different offsets.
|
||||
@@ -699,7 +707,6 @@ struct SettingsStruct
|
||||
// make sure crc is the last value in the struct
|
||||
uint8_t ProgmemMd5[16]; // crc of the binary that last saved the struct to file.
|
||||
uint8_t md5[16];
|
||||
boolean UseRTOSMultitasking;
|
||||
} Settings;
|
||||
|
||||
struct ControllerSettingsStruct
|
||||
@@ -1159,6 +1166,24 @@ enum WiFiDisconnectReason
|
||||
};
|
||||
#endif
|
||||
|
||||
enum WifiState {
|
||||
WifiOff,
|
||||
WifiStart,
|
||||
WifiTryConnect,
|
||||
WifiConnectionFailed,
|
||||
WifiClientConnectAP,
|
||||
WifiClientDisconnectAP,
|
||||
WifiCredentialsChanged,
|
||||
WifiConnectSuccess,
|
||||
WifiDisableAP,
|
||||
WifiEnableAP,
|
||||
WifiStartScan,
|
||||
};
|
||||
|
||||
WifiState currentWifiState = WifiStart;
|
||||
|
||||
void setWifiState(WifiState state);
|
||||
|
||||
// WiFi related data
|
||||
boolean wifiSetup = false;
|
||||
boolean wifiSetupConnect = false;
|
||||
@@ -1174,14 +1199,23 @@ WiFiDisconnectReason lastDisconnectReason = WIFI_DISCONNECT_REASON_UNSPECIFIED;
|
||||
unsigned long lastConnectMoment = 0;
|
||||
unsigned long lastDisconnectMoment = 0;
|
||||
unsigned long lastGetIPmoment = 0;
|
||||
unsigned long lastGetScanMoment = 0;
|
||||
unsigned long lastConnectedDuration = 0;
|
||||
bool intent_to_reboot = false;
|
||||
uint8_t lastMacConnectedAPmode[6] = {0};
|
||||
uint8_t lastMacDisconnectedAPmode[6] = {0};
|
||||
|
||||
//uint32_t scan_done_status = 0;
|
||||
uint8_t scan_done_number = 0;
|
||||
//uint8_t scan_done_scan_id = 0;
|
||||
|
||||
// Semaphore like booleans for processing data gathered from WiFi events.
|
||||
bool processedConnect = true;
|
||||
bool processedDisconnect = true;
|
||||
bool processedGetIP = true;
|
||||
|
||||
bool processedConnectAPmode = true;
|
||||
bool processedDisconnectAPmode = true;
|
||||
bool processedScanDone = true;
|
||||
|
||||
unsigned long start = 0;
|
||||
unsigned long elapsed = 0;
|
||||
@@ -1202,7 +1236,7 @@ bool firstLoop=true;
|
||||
boolean activeRuleSets[RULESETS_MAX];
|
||||
|
||||
boolean UseRTOSMultitasking;
|
||||
|
||||
|
||||
// These wifi event functions must be in a .h-file because otherwise the preprocessor
|
||||
// may not filter the ifdef checks properly.
|
||||
// Also the functions use a lot of global defined variables, so include at the end of this file.
|
||||
|
||||
+24
-19
@@ -118,6 +118,8 @@ void setup()
|
||||
stationConnectedHandler = WiFi.onStationModeConnected(onConnected);
|
||||
stationDisconnectedHandler = WiFi.onStationModeDisconnected(onDisconnect);
|
||||
stationGotIpHandler = WiFi.onStationModeGotIP(onGotIP);
|
||||
APModeStationConnectedHandler = WiFi.onSoftAPModeStationConnected(onConnectedAPmode);
|
||||
APModeStationDisconnectedHandler = WiFi.onSoftAPModeStationDisconnected(onDisonnectedAPmode);
|
||||
#endif
|
||||
|
||||
if (SpiffsSectors() < 32)
|
||||
@@ -166,13 +168,15 @@ void setup()
|
||||
saveToRTC();
|
||||
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
WiFi.setAutoReconnect(false);
|
||||
|
||||
fileSystemCheck();
|
||||
progMemMD5check();
|
||||
LoadSettings();
|
||||
checkRuleSets();
|
||||
if (strcasecmp(SecuritySettings.WifiSSID, "ssid") == 0)
|
||||
if (!selectValidWiFiSettings()) {
|
||||
wifiSetup = true;
|
||||
}
|
||||
|
||||
ExtraTaskSettings.TaskIndex = 255; // make sure this is an unused nr to prevent cache load on boot
|
||||
|
||||
@@ -195,6 +199,7 @@ void setup()
|
||||
//make sure previous serial buffers are flushed before resetting baudrate
|
||||
Serial.flush();
|
||||
Serial.begin(Settings.BaudRate);
|
||||
// Serial.setDebugOutput(true);
|
||||
}
|
||||
|
||||
if (Settings.Build != BUILD)
|
||||
@@ -235,9 +240,15 @@ void setup()
|
||||
}
|
||||
|
||||
WiFi.persistent(false); // Do not use SDK storage of SSID/WPA parameters
|
||||
WifiAPconfig();
|
||||
|
||||
WiFiConnectRelaxed();
|
||||
/*
|
||||
// FIXME TD-er:
|
||||
// Async scanning for wifi doesn't work yet like it should.
|
||||
// So no selection of strongest network yet.
|
||||
if (selectValidWiFiSettings()) {
|
||||
WifiScanAsync();
|
||||
}
|
||||
*/
|
||||
setWifiState(WifiTryConnect);
|
||||
|
||||
#ifdef FEATURE_REPORTING
|
||||
ReportStatus();
|
||||
@@ -262,12 +273,6 @@ void setup()
|
||||
vcc = ESP.getVcc() / 1000.0;
|
||||
#endif
|
||||
|
||||
// Start DNS, only used if the ESP has no valid WiFi config
|
||||
// It will reply with it's own address on all DNS requests
|
||||
// (captive portal concept)
|
||||
if (wifiSetup)
|
||||
dnsServer.start(DNS_PORT, "*", apIP);
|
||||
|
||||
if (Settings.UseRules)
|
||||
{
|
||||
String event = F("System#Boot");
|
||||
@@ -346,7 +351,7 @@ void loop()
|
||||
if (wifiSetupConnect)
|
||||
{
|
||||
// try to connect for setup wizard
|
||||
WiFiConnectRelaxed();
|
||||
setWifiState(WifiCredentialsChanged);
|
||||
wifiSetupConnect = false;
|
||||
}
|
||||
if (wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED) {
|
||||
@@ -355,8 +360,13 @@ void loop()
|
||||
if (wifiStatus == ESPEASY_WIFI_DISCONNECTED) processDisconnect();
|
||||
} else if (WiFi.status() != WL_CONNECTED) {
|
||||
// Somehow the WiFi has entered a limbo state.
|
||||
resetWiFi();
|
||||
// FIXME TD-er: This may happen on WiFi config with AP_STA mode active.
|
||||
// addLog(LOG_LEVEL_ERROR, F("Wifi status out sync"));
|
||||
// resetWiFi();
|
||||
}
|
||||
if (!processedConnectAPmode) processConnectAPmode();
|
||||
if (!processedDisconnectAPmode) processDisconnectAPmode();
|
||||
if (!processedScanDone) processScanDone();
|
||||
|
||||
bool firstLoopWiFiConnected = wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED && firstLoop;
|
||||
if (firstLoopWiFiConnected) {
|
||||
@@ -573,12 +583,7 @@ void runOncePerSecond()
|
||||
Serial.print(F(" uS 1 ps:"));
|
||||
Serial.println(timer);
|
||||
}
|
||||
|
||||
if (timerAPoff != 0 && timeOutReached(timerAPoff))
|
||||
{
|
||||
timerAPoff = 0;
|
||||
WifiAPMode(false);
|
||||
}
|
||||
checkResetFactoryPin();
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
@@ -834,7 +839,7 @@ void backgroundtasks()
|
||||
}
|
||||
|
||||
// process DNS, only used if the ESP has no valid WiFi config
|
||||
if (wifiSetup)
|
||||
if (dnsServerActive)
|
||||
dnsServer.processNextRequest();
|
||||
|
||||
#ifdef FEATURE_ARDUINO_OTA
|
||||
|
||||
+41
-1
@@ -27,6 +27,25 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) {
|
||||
wifiStatus = ESPEASY_WIFI_GOT_IP;
|
||||
processedGetIP = false;
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_STACONNECTED:
|
||||
for (byte i = 0; i < 6; ++i) {
|
||||
lastMacConnectedAPmode[i] = info.sta_connected.mac[i];
|
||||
}
|
||||
processedConnectAPmode = false;
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_STADISCONNECTED:
|
||||
for (byte i = 0; i < 6; ++i) {
|
||||
lastMacConnectedAPmode[i] = info.sta_disconnected.mac[i];
|
||||
}
|
||||
processedDisconnectAPmode = false;
|
||||
break;
|
||||
case SYSTEM_EVENT_SCAN_DONE:
|
||||
lastGetScanMoment = millis();
|
||||
// scan_done_status = info.scan_done.status;
|
||||
scan_done_number = info.scan_done.number;
|
||||
// scan_done_scan_id = info.scan_done.scan_id;
|
||||
processedScanDone = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -55,9 +74,9 @@ void onDisconnect(const WiFiEventStationModeDisconnected& event){
|
||||
lastConnectedDuration = timeDiff(last_wifi_connect_attempt_moment, lastDisconnectMoment);
|
||||
} else
|
||||
lastConnectedDuration = timeDiff(lastConnectMoment, lastDisconnectMoment);
|
||||
processedDisconnect = false;
|
||||
lastDisconnectReason = event.reason;
|
||||
wifiStatus = ESPEASY_WIFI_DISCONNECTED;
|
||||
processedDisconnect = false;
|
||||
}
|
||||
|
||||
void onGotIP(const WiFiEventStationModeGotIP& event){
|
||||
@@ -65,4 +84,25 @@ void onGotIP(const WiFiEventStationModeGotIP& event){
|
||||
wifiStatus = ESPEASY_WIFI_GOT_IP;
|
||||
processedGetIP = false;
|
||||
}
|
||||
|
||||
void onConnectedAPmode(const WiFiEventSoftAPModeStationConnected& event) {
|
||||
for (byte i = 0; i < 6; ++i) {
|
||||
lastMacConnectedAPmode[i] = event.mac[i];
|
||||
}
|
||||
processedConnectAPmode = false;
|
||||
}
|
||||
|
||||
void onDisonnectedAPmode(const WiFiEventSoftAPModeStationDisconnected& event) {
|
||||
for (byte i = 0; i < 6; ++i) {
|
||||
lastMacDisconnectedAPmode[i] = event.mac[i];
|
||||
}
|
||||
processedDisconnectAPmode = false;
|
||||
}
|
||||
|
||||
void onScanFinished(int networksFound) {
|
||||
lastGetScanMoment = millis();
|
||||
scan_done_number = networksFound;
|
||||
processedScanDone = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+421
-135
@@ -1,4 +1,5 @@
|
||||
|
||||
#define WIFI_AP_OFF_TIMER_DURATION 60000 // in milliSeconds
|
||||
|
||||
//********************************************************************************
|
||||
// Functions to process the data gathered from the events.
|
||||
@@ -6,15 +7,15 @@
|
||||
//********************************************************************************
|
||||
void processConnect() {
|
||||
if (processedConnect) return;
|
||||
processedConnect = true;
|
||||
if (wifiStatus < ESPEASY_WIFI_CONNECTED) return;
|
||||
|
||||
const long connect_duration = timeDiff(last_wifi_connect_attempt_moment, lastConnectMoment);
|
||||
String log = F("WIFI : Connected! AP: ");
|
||||
log += WiFi.SSID();
|
||||
log += F(" (");
|
||||
log += WiFi.BSSIDstr();
|
||||
log += F(") Ch: ");
|
||||
log += last_channel;
|
||||
const long connect_duration = timeDiff(last_wifi_connect_attempt_moment, lastConnectMoment);
|
||||
if (connect_duration > 0 && connect_duration < 30000) {
|
||||
// Just log times when they make sense.
|
||||
log += F(" Duration: ");
|
||||
@@ -22,17 +23,27 @@ void processConnect() {
|
||||
log += F(" ms");
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
|
||||
if (useStaticIP())
|
||||
{
|
||||
const IPAddress ip = Settings.IP;
|
||||
log = F("IP : Static IP :");
|
||||
log += ip;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
const IPAddress gw = Settings.Gateway;
|
||||
const IPAddress subnet = Settings.Subnet;
|
||||
const IPAddress dns = Settings.DNS;
|
||||
WiFi.config(ip, gw, subnet, dns);
|
||||
}
|
||||
if (Settings.UseRules && bssid_changed) {
|
||||
String event = F("WiFi#ChangedAccesspoint");
|
||||
rulesProcessing(event);
|
||||
}
|
||||
wifi_connect_attempt = 0;
|
||||
processedConnect = true;
|
||||
setWifiState(WifiConnectSuccess);
|
||||
}
|
||||
|
||||
void processDisconnect() {
|
||||
if (processedDisconnect) return;
|
||||
processedDisconnect = true;
|
||||
if (Settings.UseRules) {
|
||||
String event = F("WiFi#Disconnected");
|
||||
rulesProcessing(event);
|
||||
@@ -45,25 +56,48 @@ void processDisconnect() {
|
||||
log += format_msec_duration(lastConnectedDuration);
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
processedDisconnect = true;
|
||||
|
||||
if (Settings.deepSleep && Settings.deepSleepOnFail) {
|
||||
//only one attempt in deepsleep, to conserve battery
|
||||
addLog(LOG_LEVEL_ERROR, F("SLEEP: Connection failed, going back to sleep."));
|
||||
deepSleep(Settings.Delay);
|
||||
if (wifi_connect_attempt > 5) {
|
||||
setWifiState(WifiConnectionFailed);
|
||||
} else {
|
||||
switch (lastDisconnectReason) {
|
||||
case WIFI_DISCONNECT_REASON_NO_AP_FOUND:
|
||||
case WIFI_DISCONNECT_REASON_AUTH_FAIL:
|
||||
case WIFI_DISCONNECT_REASON_ASSOC_FAIL:
|
||||
case WIFI_DISCONNECT_REASON_HANDSHAKE_TIMEOUT:
|
||||
// Disconnect without chance for success on next attempt
|
||||
if (selectNextWiFiSettings()) {
|
||||
if (!intent_to_reboot)
|
||||
setWifiState(WifiTryConnect);
|
||||
return;
|
||||
} else {
|
||||
if (Settings.deepSleep && Settings.deepSleepOnFail) {
|
||||
//only one attempt in deepsleep, to conserve battery
|
||||
addLog(LOG_LEVEL_ERROR, F("SLEEP: Connection failed, going back to sleep."));
|
||||
deepSleep(Settings.Delay);
|
||||
}
|
||||
setWifiState(WifiConnectionFailed);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
setWifiState(WifiStart);
|
||||
if (!intent_to_reboot)
|
||||
setWifiState(WifiTryConnect);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!intent_to_reboot)
|
||||
WiFiConnectRelaxed();
|
||||
}
|
||||
|
||||
|
||||
void processGotIP() {
|
||||
if (processedGetIP)
|
||||
return;
|
||||
processedGetIP = true;
|
||||
if (wifiStatus < ESPEASY_WIFI_GOT_IP)
|
||||
return;
|
||||
IPAddress ip = WiFi.localIP();
|
||||
if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0)
|
||||
return;
|
||||
const IPAddress gw = WiFi.gatewayIP();
|
||||
const IPAddress subnet = WiFi.subnetMask();
|
||||
String log = F("WIFI : ");
|
||||
@@ -126,19 +160,323 @@ void processGotIP() {
|
||||
rulesProcessing(event);
|
||||
}
|
||||
statusLED(true);
|
||||
// WiFi.scanDelete();
|
||||
wifiStatus = ESPEASY_WIFI_SERVICES_INITIALIZED;
|
||||
processedGetIP = true;
|
||||
if (wifiSetup) {
|
||||
// Wifi setup was active, Apparently these settings work.
|
||||
wifiSetup = false;
|
||||
SaveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void processConnectAPmode() {
|
||||
if (processedConnectAPmode) return;
|
||||
processedConnectAPmode = true;
|
||||
String log = F("AP Mode: Client connected: ");
|
||||
log += formatMAC(lastMacConnectedAPmode);
|
||||
log += F(" Connected devices: ");
|
||||
log += WiFi.softAPgetStationNum();
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
setWifiState(WifiClientConnectAP);
|
||||
}
|
||||
|
||||
void processDisconnectAPmode() {
|
||||
if (processedDisconnectAPmode) return;
|
||||
processedDisconnectAPmode = true;
|
||||
const int nrStationsConnected = WiFi.softAPgetStationNum();
|
||||
String log = F("AP Mode: Client disconnected: ");
|
||||
log += formatMAC(lastMacDisconnectedAPmode);
|
||||
log += F(" Connected devices: ");
|
||||
log += nrStationsConnected;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (nrStationsConnected == 0) {
|
||||
setWifiState(WifiClientDisconnectAP);
|
||||
}
|
||||
}
|
||||
|
||||
void processScanDone() {
|
||||
if (processedScanDone) return;
|
||||
processedScanDone = true;
|
||||
String log = F("WIFI : Scan finished, found: ");
|
||||
log += scan_done_number;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
|
||||
int bestScanID = -1;
|
||||
int32_t bestRssi = -1000;
|
||||
uint8_t bestWiFiSettings = lastWiFiSettings;
|
||||
if (selectValidWiFiSettings()) {
|
||||
bool done = false;
|
||||
String lastWiFiSettingsSSID = getLastWiFiSettingsSSID();
|
||||
for (int settingNr = 0; !done && settingNr < 2; ++settingNr) {
|
||||
for (int i = 0; i < scan_done_number; ++i) {
|
||||
if (WiFi.SSID(i) == lastWiFiSettingsSSID) {
|
||||
int32_t rssi = WiFi.RSSI(i);
|
||||
if (bestRssi < rssi) {
|
||||
bestRssi = rssi;
|
||||
bestScanID = i;
|
||||
bestWiFiSettings = lastWiFiSettings;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!selectNextWiFiSettings()) done = true;
|
||||
}
|
||||
if (bestScanID >= 0) {
|
||||
log = F("WIFI : Selected: ");
|
||||
log += formatScanResult(bestScanID, " ");
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
lastWiFiSettings = bestWiFiSettings;
|
||||
uint8_t * scanbssid = WiFi.BSSID(bestScanID);
|
||||
if (scanbssid) {
|
||||
for (int i = 0; i < 6 ; ++i) {
|
||||
lastBSSID[i] = *(scanbssid + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
setWifiState(WifiTryConnect);
|
||||
}
|
||||
}
|
||||
|
||||
void resetWiFi() {
|
||||
WiFiMode_t currentMode = WiFi.getMode();
|
||||
WiFi.mode(WIFI_OFF);
|
||||
WiFi.mode(currentMode);
|
||||
addLog(LOG_LEVEL_INFO, F("Reset WiFi."));
|
||||
setWifiState(WifiOff);
|
||||
setWifiState(WifiStart);
|
||||
lastDisconnectMoment = millis();
|
||||
processedDisconnect = false;
|
||||
wifiStatus = ESPEASY_WIFI_DISCONNECTED;
|
||||
}
|
||||
|
||||
void WifiScanAsync() {
|
||||
setWifiState(WifiStartScan);
|
||||
addLog(LOG_LEVEL_INFO, F("WIFI : Start network scan"));
|
||||
#ifdef ESP32
|
||||
bool async = true;
|
||||
bool show_hidden = false;
|
||||
bool passive = false;
|
||||
uint32_t max_ms_per_chan = 300;
|
||||
WiFi.scanNetworks(async, show_hidden, passive, max_ms_per_chan);
|
||||
#else
|
||||
// 2.4.x only and it doesn't work like expected.
|
||||
// WiFi.scanNetworksAsync(onScanFinished);
|
||||
#endif
|
||||
}
|
||||
|
||||
//********************************************************************************
|
||||
// WiFi state
|
||||
//********************************************************************************
|
||||
// 0 Wifi off
|
||||
// 1 Start => STA
|
||||
// 2 Try connect => STA => successful, goto 7
|
||||
// 3 Connection fails => AP => no client in N seconds, goto 1
|
||||
// 4 Client connects => AP
|
||||
// 5 Credentials changed => STA_AP => goto 2
|
||||
// 6 Connect successful (AP on) => STA_AP => disable AP after N seconds, goto 8
|
||||
// 7 Connect successful => STA
|
||||
// 8 Disable AP after N seconds => STA
|
||||
//********************************************************************************
|
||||
|
||||
bool WifiIsAP(WiFiMode_t wifimode)
|
||||
{
|
||||
#if defined(ESP32)
|
||||
return (wifimode == WIFI_MODE_AP) || (wifimode == WIFI_MODE_APSTA);
|
||||
#else
|
||||
return (wifimode == WIFI_AP) || (wifimode == WIFI_AP_STA);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool WifiIsSTA(WiFiMode_t wifimode)
|
||||
{
|
||||
#if defined(ESP32)
|
||||
return ((wifimode & WIFI_MODE_STA) != 0);
|
||||
#else
|
||||
return ((wifimode & WIFI_STA) != 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void setWifiState(WifiState state) {
|
||||
currentWifiState = state;
|
||||
switch (state) {
|
||||
case WifiOff:
|
||||
WifiDisconnect();
|
||||
changeWifiMode(WIFI_OFF);
|
||||
break;
|
||||
case WifiStart:
|
||||
changeWifiMode(WIFI_STA);
|
||||
break;
|
||||
case WifiConnectionFailed:
|
||||
addLog(LOG_LEVEL_INFO, F("WIFI : Connection Failed"));
|
||||
if (WIFI_AP != WiFi.getMode()) {
|
||||
changeWifiMode(WIFI_AP);
|
||||
wifiSetup = true;
|
||||
timerAPoff = millis() + WIFI_AP_OFF_TIMER_DURATION;
|
||||
}
|
||||
break;
|
||||
case WifiClientConnectAP:
|
||||
timerAPoff = 0; // Disable timer to switch AP off.
|
||||
changeWifiMode(WIFI_AP);
|
||||
break;
|
||||
case WifiClientDisconnectAP:
|
||||
if (WifiIsAP(WiFi.getMode())) {
|
||||
timerAPoff = millis() + WIFI_AP_OFF_TIMER_DURATION;
|
||||
}
|
||||
break;
|
||||
case WifiCredentialsChanged:
|
||||
lastWiFiSettings = 0; // Force to load the first settings.
|
||||
wifi_connect_attempt = 0;
|
||||
// fall through
|
||||
case WifiTryConnect:
|
||||
if (WifiIsAP(WiFi.getMode())) {
|
||||
timerAPoff = 0; // Disable timer to switch AP off.
|
||||
changeWifiMode(WIFI_AP_STA);
|
||||
} else {
|
||||
changeWifiMode(WIFI_STA);
|
||||
}
|
||||
if (prepareWiFi()) {
|
||||
tryConnectWiFi();
|
||||
} else {
|
||||
setWifiState(WifiConnectionFailed);
|
||||
}
|
||||
break;
|
||||
case WifiConnectSuccess:
|
||||
if (WifiIsAP(WiFi.getMode())) {
|
||||
timerAPoff = millis() + WIFI_AP_OFF_TIMER_DURATION;
|
||||
} else {
|
||||
timerAPoff = 0; // Disable timer to switch AP off.
|
||||
changeWifiMode(WIFI_STA);
|
||||
}
|
||||
wifi_connect_attempt = 0;
|
||||
break;
|
||||
case WifiDisableAP:
|
||||
if (WifiIsAP(WiFi.getMode())) {
|
||||
timerAPoff = 0; // Disable timer to switch AP off.
|
||||
changeWifiMode(WIFI_STA);
|
||||
}
|
||||
break;
|
||||
case WifiEnableAP:
|
||||
if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED) {
|
||||
changeWifiMode(WIFI_AP_STA);
|
||||
} else {
|
||||
changeWifiMode(WIFI_AP);
|
||||
}
|
||||
timerAPoff = millis() + WIFI_AP_OFF_TIMER_DURATION;
|
||||
break;
|
||||
case WifiStartScan:
|
||||
if (WifiIsAP(WiFi.getMode())) {
|
||||
changeWifiMode(WIFI_AP_STA);
|
||||
} else changeWifiMode(WIFI_STA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************************************************
|
||||
// Set Wifi AP Mode
|
||||
//********************************************************************************
|
||||
void setWifiMode(WiFiMode_t wifimode) {
|
||||
switch (wifimode) {
|
||||
case WIFI_OFF:
|
||||
addLog(LOG_LEVEL_INFO, F("WIFI : Switch off WiFi"));
|
||||
break;
|
||||
case WIFI_STA:
|
||||
addLog(LOG_LEVEL_INFO, F("WIFI : Set WiFi to STA"));
|
||||
break;
|
||||
case WIFI_AP:
|
||||
addLog(LOG_LEVEL_INFO, F("WIFI : Set WiFi to AP"));
|
||||
break;
|
||||
case WIFI_AP_STA:
|
||||
addLog(LOG_LEVEL_INFO, F("WIFI : Set WiFi to AP+STA"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
WiFi.mode(wifimode);
|
||||
}
|
||||
|
||||
void changeWifiMode(WiFiMode_t wifimode)
|
||||
{
|
||||
if (wifimode == WiFi.getMode()) return;
|
||||
if (WiFi.getMode() == WIFI_OFF) {
|
||||
// Any mode can be selected, starting from off mode.
|
||||
addLog(LOG_LEVEL_INFO, F("WIFI : Switch on WiFi"));
|
||||
setWifiMode(wifimode);
|
||||
return;
|
||||
}
|
||||
switch (wifimode) {
|
||||
case WIFI_OFF:
|
||||
WifiDisconnect();
|
||||
setWifiMode(WIFI_OFF);
|
||||
return;
|
||||
case WIFI_STA:
|
||||
if (WifiIsAP(WiFi.getMode())) {
|
||||
// Change from AP mode to STA mode, must disconnect clients.
|
||||
dnsServerActive = false;
|
||||
dnsServer.stop();
|
||||
if (WiFi.softAPdisconnect(true)) {
|
||||
String log("WIFI : AP Mode Disabled for SSID: ");
|
||||
log += WifiGetAPssid();
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
} else {
|
||||
String log("WIFI : Error while disabling AP Mode with SSID: ");
|
||||
log += WifiGetAPssid();
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
}
|
||||
}
|
||||
setWifiMode(wifimode);
|
||||
WiFi.reconnect();
|
||||
break;
|
||||
case WIFI_AP_STA:
|
||||
case WIFI_AP:
|
||||
{
|
||||
if (WifiIsSTA(WiFi.getMode())) {
|
||||
// Should disable WiFi first and then restart in AP mode.
|
||||
WifiDisconnect();
|
||||
if (wifimode == WIFI_AP_STA) {
|
||||
WiFi.reconnect();
|
||||
}
|
||||
// setWifiMode(WIFI_OFF);
|
||||
delay(100);
|
||||
}
|
||||
// create and store unique AP SSID/PW to prevent ESP from starting AP mode with default SSID and No password!
|
||||
// setup ssid for AP Mode when needed
|
||||
setWifiMode(wifimode);
|
||||
WiFi.setAutoConnect(false);
|
||||
String softAPSSID=WifiGetAPssid();
|
||||
String pwd = SecuritySettings.WifiAPKey;
|
||||
IPAddress subnet(DEFAULT_AP_SUBNET);
|
||||
if (!WiFi.softAPConfig(apIP, apIP, subnet)) {
|
||||
addLog(LOG_LEVEL_ERROR, "WIFI : [AP] softAPConfig failed!");
|
||||
}
|
||||
if (WiFi.softAP(softAPSSID.c_str(),pwd.c_str())) {
|
||||
String log("WIFI : AP Mode ssid will be ");
|
||||
log += softAPSSID;
|
||||
log += F(" with address ");
|
||||
log += WiFi.softAPIP().toString();
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
} else {
|
||||
String log("WIFI : Error while starting AP Mode with SSID: ");
|
||||
log += softAPSSID;
|
||||
log += F(" IP: ");
|
||||
log += apIP.toString();
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
}
|
||||
#ifdef ESP32
|
||||
|
||||
#else
|
||||
if(wifi_softap_dhcps_status() != DHCP_STARTED) {
|
||||
if(!wifi_softap_dhcps_start()) {
|
||||
addLog(LOG_LEVEL_ERROR, "WIFI : [AP] wifi_softap_dhcps_start failed!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Start DNS, only used if the ESP has no valid WiFi config
|
||||
// It will reply with it's own address on all DNS requests
|
||||
// (captive portal concept)
|
||||
dnsServerActive = true;
|
||||
dnsServer.start(DNS_PORT, "*", apIP);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************************************************
|
||||
// Determine Wifi AP name to set. (also used for mDNS)
|
||||
@@ -146,7 +484,7 @@ void resetWiFi() {
|
||||
String WifiGetAPssid()
|
||||
{
|
||||
String ssid(Settings.Name);
|
||||
ssid+=F("-");
|
||||
ssid+=F("_");
|
||||
ssid+=Settings.Unit;
|
||||
return (ssid);
|
||||
}
|
||||
@@ -163,65 +501,6 @@ String WifiGetHostname()
|
||||
}
|
||||
|
||||
|
||||
//********************************************************************************
|
||||
// Set Wifi AP Mode config
|
||||
//********************************************************************************
|
||||
void WifiAPconfig()
|
||||
{
|
||||
// create and store unique AP SSID/PW to prevent ESP from starting AP mode with default SSID and No password!
|
||||
// setup ssid for AP Mode when needed
|
||||
|
||||
String softAPSSID=WifiGetAPssid();
|
||||
String pwd = SecuritySettings.WifiAPKey;
|
||||
WiFi.softAP(softAPSSID.c_str(),pwd.c_str());
|
||||
// We start in STA mode
|
||||
WifiAPMode(false);
|
||||
|
||||
String log("WIFI : AP Mode ssid will be ");
|
||||
log=log+WifiGetAPssid();
|
||||
|
||||
log=log+F(" with address ");
|
||||
log=log+apIP.toString();
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
|
||||
|
||||
bool WifiIsAP()
|
||||
{
|
||||
#if defined(ESP8266)
|
||||
byte wifimode = wifi_get_opmode();
|
||||
#endif
|
||||
#if defined(ESP32)
|
||||
byte wifimode = WiFi.getMode();
|
||||
#endif
|
||||
return(wifimode == 2 || wifimode == 3); //apmode is enabled
|
||||
}
|
||||
|
||||
//********************************************************************************
|
||||
// Set Wifi AP Mode
|
||||
//********************************************************************************
|
||||
void WifiAPMode(boolean state)
|
||||
{
|
||||
if (WifiIsAP())
|
||||
{
|
||||
//want to disable?
|
||||
if (!state)
|
||||
{
|
||||
WiFi.mode(WIFI_STA);
|
||||
addLog(LOG_LEVEL_INFO, F("WIFI : AP Mode disabled"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//want to enable?
|
||||
if (state)
|
||||
{
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
addLog(LOG_LEVEL_INFO, F("WIFI : AP Mode enabled"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool useStaticIP() {
|
||||
return (Settings.IP[0] != 0 && Settings.IP[0] != 255);
|
||||
}
|
||||
@@ -230,9 +509,10 @@ bool useStaticIP() {
|
||||
// Set Wifi config
|
||||
//********************************************************************************
|
||||
bool prepareWiFi() {
|
||||
if (!selectValidWiFiSettings())
|
||||
if (!selectValidWiFiSettings()) {
|
||||
addLog(LOG_LEVEL_ERROR, F("WIFI : No valid wifi settings"));
|
||||
return false;
|
||||
|
||||
}
|
||||
String log = "";
|
||||
char hostname[40];
|
||||
strncpy(hostname, WifiGetHostname().c_str(), sizeof(hostname));
|
||||
@@ -242,35 +522,9 @@ bool prepareWiFi() {
|
||||
#if defined(ESP32)
|
||||
WiFi.setHostname(hostname);
|
||||
#endif
|
||||
|
||||
//use static ip?
|
||||
if (useStaticIP())
|
||||
{
|
||||
const IPAddress ip = Settings.IP;
|
||||
log = F("IP : Static IP :");
|
||||
log += ip;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
const IPAddress gw = Settings.Gateway;
|
||||
const IPAddress subnet = Settings.Subnet;
|
||||
const IPAddress dns = Settings.DNS;
|
||||
WiFi.config(ip, gw, subnet, dns);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//********************************************************************************
|
||||
// Start connect to WiFi and check later to see if connected.
|
||||
//********************************************************************************
|
||||
void WiFiConnectRelaxed() {
|
||||
if (prepareWiFi()) {
|
||||
tryConnectWiFi();
|
||||
return;
|
||||
}
|
||||
addLog(LOG_LEVEL_ERROR, F("WIFI : Could not connect to AP! (relaxed connect mode)"));
|
||||
//everything failed, activate AP mode (will deactivate automatically after a while if its connected again)
|
||||
WifiAPMode(true);
|
||||
}
|
||||
|
||||
|
||||
//********************************************************************************
|
||||
// Manage WiFi credentials
|
||||
@@ -304,7 +558,7 @@ bool wifiSettingsValid(const char* ssid, const char* pass) {
|
||||
if (ssid[0] == 0 || (strcasecmp(ssid, "ssid") == 0)) {
|
||||
return false;
|
||||
}
|
||||
if (pass[0] == 0) return false;
|
||||
// if (pass[0] == 0) return false; // Allow for empty pass
|
||||
if (strlen(ssid) > 32) return false;
|
||||
if (strlen(pass) > 64) return false;
|
||||
return true;
|
||||
@@ -316,7 +570,7 @@ bool wifiConnectTimeoutReached() {
|
||||
// Connection attempt was already ended.
|
||||
return true;
|
||||
}
|
||||
if (wifiSetupConnect) {
|
||||
if (WifiIsAP(WiFi.getMode())) {
|
||||
// Initial setup of WiFi, may take much longer since accesspoint is still active.
|
||||
return timeOutReached(last_wifi_connect_attempt_moment + 20000);
|
||||
}
|
||||
@@ -335,26 +589,20 @@ bool wifiConnectTimeoutReached() {
|
||||
// Simply start the WiFi connection sequence
|
||||
//********************************************************************************
|
||||
bool tryConnectWiFi() {
|
||||
if (wifiSetup && !wifiSetupConnect)
|
||||
return false;
|
||||
if (wifiStatus != ESPEASY_WIFI_DISCONNECTED)
|
||||
return(true); //already connected, need to disconnect first
|
||||
// if (wifiSetup && !wifiSetupConnect)
|
||||
// return false;
|
||||
if (wifiStatus != ESPEASY_WIFI_DISCONNECTED) {
|
||||
if (!WifiIsAP(WiFi.getMode())) {
|
||||
// Only when not in AP mode.
|
||||
return(true); //already connected, need to disconnect first
|
||||
}
|
||||
}
|
||||
if (!wifiConnectTimeoutReached())
|
||||
return true; // timeout not reached yet, thus no need to retry again.
|
||||
if (!selectValidWiFiSettings()) {
|
||||
addLog(LOG_LEVEL_ERROR, F("WIFI : No valid WiFi settings!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wifi_connect_attempt != 0 && ((wifi_connect_attempt % 3) == 0)) {
|
||||
// Change to other wifi settings.
|
||||
if (selectNextWiFiSettings())
|
||||
WiFi.disconnect();
|
||||
}
|
||||
if (wifi_connect_attempt > 6) {
|
||||
//everything failed, activate AP mode (will deactivate automatically after a while if its connected again)
|
||||
WifiAPMode(true);
|
||||
}
|
||||
const char* ssid = getLastWiFiSettingsSSID();
|
||||
const char* passphrase = getLastWiFiSettingsPassphrase();
|
||||
String log = F("WIFI : Connecting ");
|
||||
@@ -399,7 +647,13 @@ bool tryConnectWiFi() {
|
||||
//********************************************************************************
|
||||
void WifiDisconnect()
|
||||
{
|
||||
WiFi.disconnect();
|
||||
#if defined(ESP32)
|
||||
WiFi.disconnect();
|
||||
#else
|
||||
ETS_UART_INTR_DISABLE();
|
||||
wifi_station_disconnect();
|
||||
ETS_UART_INTR_ENABLE();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -424,17 +678,44 @@ void WifiScan()
|
||||
Serial.print(F("WIFI : "));
|
||||
Serial.print(i + 1);
|
||||
Serial.print(": ");
|
||||
Serial.print(WiFi.SSID(i));
|
||||
Serial.print(" (");
|
||||
Serial.print(WiFi.RSSI(i));
|
||||
Serial.print(")");
|
||||
Serial.println("");
|
||||
Serial.println(formatScanResult(i, " "));
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
String formatScanResult(int i, const String& separator) {
|
||||
String result = WiFi.SSID(i);
|
||||
result += separator;
|
||||
result += WiFi.BSSIDstr(i);
|
||||
result += separator;
|
||||
result += F("Ch:");
|
||||
result += WiFi.channel(i);
|
||||
result += F(" (");
|
||||
result += WiFi.RSSI(i);
|
||||
result += F("dBm) ");
|
||||
switch (WiFi.encryptionType(i)) {
|
||||
#ifdef ESP32
|
||||
case WIFI_AUTH_OPEN: result += F("open"); break;
|
||||
case WIFI_AUTH_WEP: result += F("WEP"); break;
|
||||
case WIFI_AUTH_WPA_PSK: result += F("WPA/PSK"); break;
|
||||
case WIFI_AUTH_WPA2_PSK: result += F("WPA2/PSK"); break;
|
||||
case WIFI_AUTH_WPA_WPA2_PSK: result += F("WPA/WPA2/PSK"); break;
|
||||
case WIFI_AUTH_WPA2_ENTERPRISE: result += F("WPA2 Enterprise"); break;
|
||||
#else
|
||||
case ENC_TYPE_WEP: result += F("WEP"); break;
|
||||
case ENC_TYPE_TKIP: result += F("WPA/PSK"); break;
|
||||
case ENC_TYPE_CCMP: result += F("WPA2/PSK"); break;
|
||||
case ENC_TYPE_NONE: result += F("open"); break;
|
||||
case ENC_TYPE_AUTO: result += F("WPA/WPA2/PSK"); break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//********************************************************************************
|
||||
// Check if we are still connected to a Wifi AP
|
||||
@@ -444,20 +725,24 @@ void WifiCheck()
|
||||
if(wifiSetup)
|
||||
return;
|
||||
|
||||
if (WifiIsAP(WiFi.getMode())) {
|
||||
// disable AP after timeout.
|
||||
if (timerAPoff && timeOutReached(timerAPoff)) {
|
||||
setWifiState(WifiDisableAP);
|
||||
}
|
||||
}
|
||||
|
||||
if (wifiStatus == ESPEASY_WIFI_DISCONNECTED)
|
||||
{
|
||||
NC_Count++;
|
||||
WiFiConnectRelaxed();
|
||||
if (!WifiIsAP(WiFi.getMode()))
|
||||
setWifiState(WifiTryConnect);
|
||||
}
|
||||
//connected
|
||||
else
|
||||
else if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED)
|
||||
{
|
||||
C_Count++;
|
||||
NC_Count = 0;
|
||||
if (C_Count > 2) // disable AP after timeout if a Wifi connection is established...
|
||||
{
|
||||
WifiAPMode(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,7 +751,7 @@ void WifiCheck()
|
||||
//********************************************************************************
|
||||
bool getSubnetRange(IPAddress& low, IPAddress& high)
|
||||
{
|
||||
if (WifiIsAP()) {
|
||||
if (WifiIsAP(WiFi.getMode())) {
|
||||
// WiFi is active as accesspoint, do not check.
|
||||
return false;
|
||||
}
|
||||
@@ -487,6 +772,7 @@ bool getSubnetRange(IPAddress& low, IPAddress& high)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
String getLastDisconnectReason() {
|
||||
switch (lastDisconnectReason) {
|
||||
case WIFI_DISCONNECT_REASON_UNSPECIFIED: return F("Unspecified");
|
||||
|
||||
@@ -26,6 +26,9 @@ void hardwareInit()
|
||||
break;
|
||||
}
|
||||
|
||||
if (Settings.Pin_Reset != -1)
|
||||
pinMode(Settings.Pin_Reset,INPUT_PULLUP);
|
||||
|
||||
// configure hardware pins according to eeprom settings.
|
||||
if (Settings.Pin_i2c_sda != -1)
|
||||
{
|
||||
@@ -97,3 +100,27 @@ void hardwareInit()
|
||||
|
||||
}
|
||||
|
||||
void checkResetFactoryPin(){
|
||||
static byte factoryResetCounter=0;
|
||||
if (Settings.Pin_Reset == -1)
|
||||
return;
|
||||
|
||||
if (digitalRead(Settings.Pin_Reset) == 0){ // active low reset pin
|
||||
factoryResetCounter++; // just count every second
|
||||
}
|
||||
else
|
||||
{ // reset pin released
|
||||
if (factoryResetCounter > 9) // factory reset and reboot
|
||||
ResetFactory();
|
||||
if (factoryResetCounter > 3) // normal reboot
|
||||
#if defined(ESP8266)
|
||||
ESP.reset();
|
||||
#endif
|
||||
#if defined(ESP32)
|
||||
ESP.restart();
|
||||
#endif
|
||||
|
||||
factoryResetCounter = 0; // count was < 3, reset counter
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+66
-28
@@ -332,7 +332,7 @@ void statusLED(boolean traffic)
|
||||
}
|
||||
}
|
||||
//AP mode is active
|
||||
else if (WifiIsAP())
|
||||
else if (WifiIsAP(WiFi.getMode()))
|
||||
{
|
||||
nStatusValue = ((millis()>>1) & PWMRANGE) - (PWMRANGE>>2); //ramp up for 2 sec, 3/4 luminosity
|
||||
}
|
||||
@@ -482,6 +482,13 @@ String BuildFixes()
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.Build < 20101)
|
||||
{
|
||||
Serial.println(F("Fix reset Pin"));
|
||||
Settings.Pin_Reset = -1;
|
||||
}
|
||||
|
||||
Settings.Build = BUILD;
|
||||
return(SaveSettings());
|
||||
}
|
||||
@@ -694,25 +701,36 @@ String SaveSettings(void)
|
||||
{
|
||||
checkRAM(F("SaveSettings"));
|
||||
MD5Builder md5;
|
||||
uint8_t tmp_md5[16] = {0};
|
||||
memcpy( Settings.ProgmemMd5, CRCValues.runTimeMD5, 16);
|
||||
md5.begin();
|
||||
md5.add((uint8_t *)&Settings, sizeof(Settings)-16);
|
||||
md5.calculate();
|
||||
md5.getBytes(Settings.md5);
|
||||
|
||||
md5.getBytes(tmp_md5);
|
||||
String err;
|
||||
err=SaveToFile((char*)FILE_CONFIG, 0, (byte*)&Settings, sizeof(struct SettingsStruct));
|
||||
if (err.length())
|
||||
return(err);
|
||||
if (memcmp(tmp_md5, Settings.md5, 16) != 0) {
|
||||
// Settings have changed, save to file.
|
||||
memcpy(Settings.md5, tmp_md5, 16);
|
||||
err=SaveToFile((char*)FILE_CONFIG, 0, (byte*)&Settings, sizeof(struct SettingsStruct));
|
||||
if (err.length())
|
||||
return(err);
|
||||
}
|
||||
|
||||
memcpy( SecuritySettings.ProgmemMd5, CRCValues.runTimeMD5, 16);
|
||||
md5.begin();
|
||||
md5.add((uint8_t *)&SecuritySettings, sizeof(SecuritySettings)-16);
|
||||
md5.calculate();
|
||||
md5.getBytes(SecuritySettings.md5);
|
||||
err=SaveToFile((char*)FILE_SECURITY, 0, (byte*)&SecuritySettings, sizeof(struct SecurityStruct));
|
||||
|
||||
return (err);
|
||||
md5.getBytes(tmp_md5);
|
||||
if (memcmp(tmp_md5, SecuritySettings.md5, 16) != 0) {
|
||||
// Settings have changed, save to file.
|
||||
memcpy(SecuritySettings.md5, tmp_md5, 16);
|
||||
err=SaveToFile((char*)FILE_SECURITY, 0, (byte*)&SecuritySettings, sizeof(struct SecurityStruct));
|
||||
if (WifiIsAP(WiFi.getMode())) {
|
||||
// Security settings are saved, may be update of WiFi settings or hostname.
|
||||
wifiSetupConnect = true;
|
||||
}
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
@@ -1095,6 +1113,7 @@ void ResetFactory(void)
|
||||
Settings.Pin_status_led = -1;
|
||||
Settings.Pin_status_led_Inversed = true;
|
||||
Settings.Pin_sd_cs = -1;
|
||||
Settings.Pin_Reset = -1;
|
||||
Settings.Protocol[0] = DEFAULT_PROTOCOL;
|
||||
strcpy_P(Settings.Name, PSTR(DEFAULT_NAME));
|
||||
Settings.deepSleep = false;
|
||||
@@ -1168,7 +1187,7 @@ void ResetFactory(void)
|
||||
delay(1000);
|
||||
WiFi.persistent(true); // use SDK storage of SSID/WPA parameters
|
||||
intent_to_reboot = true;
|
||||
WiFi.disconnect(); // this will store empty ssid/wpa into sdk storage
|
||||
WifiDisconnect(); // this will store empty ssid/wpa into sdk storage
|
||||
WiFi.persistent(false); // Do not use SDK storage of SSID/WPA parameters
|
||||
#if defined(ESP8266)
|
||||
ESP.reset();
|
||||
@@ -1313,6 +1332,8 @@ boolean loglevelActiveFor(byte destination, byte logLevel) {
|
||||
case LOG_TO_SERIAL: {
|
||||
if (!SerialAvailableForWrite()) return false;
|
||||
logLevelSettings = Settings.SerialLogLevel;
|
||||
if (wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED)
|
||||
logLevelSettings = 2;
|
||||
break;
|
||||
}
|
||||
case LOG_TO_SYSLOG: {
|
||||
@@ -1341,6 +1362,8 @@ boolean loglevelActive(byte logLevel, byte logLevelSettings) {
|
||||
void addLog(byte logLevel, const char *line)
|
||||
{
|
||||
if (loglevelActiveFor(LOG_TO_SERIAL, logLevel)) {
|
||||
Serial.print(millis());
|
||||
Serial.print(F(" : "));
|
||||
Serial.println(line);
|
||||
}
|
||||
if (loglevelActiveFor(LOG_TO_SYSLOG, logLevel)) {
|
||||
@@ -1556,25 +1579,40 @@ String parseTemplate(String &tmpString, byte lineSize)
|
||||
else
|
||||
value = toString(UserVar[y * VARS_PER_TASK + z], ExtraTaskSettings.TaskDeviceValueDecimals[z]);
|
||||
|
||||
int oidx;
|
||||
if ((oidx = valueFormat.indexOf('O')) >= 0) // Output
|
||||
if (valueFormat.length() > 0) //do the checks only if a Format is defined to optimize loop
|
||||
{
|
||||
valueFormat.remove(oidx);
|
||||
oidx = valueFormat.indexOf('!'); // inverted or active low
|
||||
float val = value.toFloat();
|
||||
if (oidx >= 0) {
|
||||
valueFormat.remove(oidx);
|
||||
value = val == 0 ? " ON" : "OFF";
|
||||
} else {
|
||||
value = val == 0 ? "OFF" : " ON";
|
||||
}
|
||||
}
|
||||
const int val = value == "0" ? 0 : 1; //to be used for GPIO status (0 or 1)
|
||||
const float valFloat = value.toFloat();
|
||||
const int inverted = valueFormat.indexOf('!') >= 0 ? 1 : 0;
|
||||
|
||||
if (valueFormat == "R")
|
||||
{
|
||||
int filler = lineSize - newString.length() - value.length() - tmpString.length() ;
|
||||
for (byte f = 0; f < filler; f++)
|
||||
newString += " ";
|
||||
if (valueFormat.indexOf('O') >= 0)
|
||||
value = val == inverted ? "OFF" : " ON"; //(equivalent to XOR operator)
|
||||
else if (valueFormat.indexOf('C') >= 0)
|
||||
value = val == inverted ? "CLOSE" : " OPEN";
|
||||
else if (valueFormat.indexOf('U') >= 0)
|
||||
value = val == inverted ? "DOWN" : " UP";
|
||||
else if (valueFormat.indexOf('Y') >= 0)
|
||||
value = val == inverted ? " NO" : "YES";
|
||||
else if (valueFormat.indexOf('y') >= 0)
|
||||
value = val == inverted ? "N" : "Y";
|
||||
else if (valueFormat.indexOf('X') >= 0)
|
||||
value = val == inverted ? "O" : "X";
|
||||
else if (valueFormat.indexOf('I') >= 0)
|
||||
value = val == inverted ? "OUT" : " IN";
|
||||
else if (valueFormat.indexOf('Z') >= 0) // return "0" or "1"
|
||||
value = val == inverted ? "0" : "1";
|
||||
else if (valueFormat.indexOf('D') >= 0) // round to the nearest integer
|
||||
value = (int)roundf(valFloat);
|
||||
else if (valueFormat.indexOf('F') >= 0) // FLOOR (round down)
|
||||
value = (int)floorf(valFloat);
|
||||
else if (valueFormat.indexOf('E') >= 0) // CEILING (round up)
|
||||
value = (int)ceilf(valFloat);
|
||||
|
||||
if (valueFormat.indexOf('R') >= 0) {
|
||||
int filler = lineSize - newString.length() - value.length() - tmpString.length() ;
|
||||
for (byte f = 0; f < filler; f++)
|
||||
newString += " ";
|
||||
}
|
||||
}
|
||||
newString += String(value);
|
||||
break;
|
||||
|
||||
@@ -54,6 +54,12 @@ void formatMAC(const uint8_t* mac, char (&strMAC)[20]) {
|
||||
sprintf_P(strMAC, PSTR("%02X:%02X:%02X:%02X:%02X:%02X"), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
String formatMAC(const uint8_t* mac) {
|
||||
char str[20];
|
||||
formatMAC(mac, str);
|
||||
return String(str);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
Workaround for removing trailing white space when String() converts a float with 0 decimals
|
||||
\*********************************************************************************************/
|
||||
@@ -280,6 +286,8 @@ void parseSystemVariables(String& s, boolean useURLencode)
|
||||
SMART_REPL(F("%ip%"),WiFi.localIP().toString())
|
||||
SMART_REPL(F("%rssi%"), String((wifiStatus == ESPEASY_WIFI_DISCONNECTED) ? 0 : WiFi.RSSI()))
|
||||
SMART_REPL(F("%ssid%"), (wifiStatus == ESPEASY_WIFI_DISCONNECTED) ? F("--") : WiFi.SSID())
|
||||
SMART_REPL(F("%bssid%"), (wifiStatus == ESPEASY_WIFI_DISCONNECTED) ? F("00:00:00:00:00:00") : WiFi.BSSIDstr())
|
||||
SMART_REPL(F("%wi_ch%"), String((wifiStatus == ESPEASY_WIFI_DISCONNECTED) ? 0 : WiFi.channel()))
|
||||
SMART_REPL(F("%unit%"), String(Settings.Unit))
|
||||
SMART_REPL(F("%mac%"), String(WiFi.macAddress()))
|
||||
#if defined(ESP8266)
|
||||
@@ -288,6 +296,7 @@ void parseSystemVariables(String& s, boolean useURLencode)
|
||||
|
||||
if (s.indexOf(F("%sys")) != -1) {
|
||||
SMART_REPL(F("%sysload%"), String(100 - (100 * loopCounterLast / loopCounterMax)))
|
||||
SMART_REPL(F("%sysheap%"), String(ESP.getFreeHeap()));
|
||||
SMART_REPL(F("%systm_hm%"), getTimeString(':', false))
|
||||
SMART_REPL(F("%systm_hm_am%"), getTimeString_ampm(':', false))
|
||||
SMART_REPL(F("%systime%"), getTimeString(':'))
|
||||
@@ -300,6 +309,7 @@ void parseSystemVariables(String& s, boolean useURLencode)
|
||||
SMART_REPL_TIME(F("%syshour%"), PSTR("%02d"), hour())
|
||||
SMART_REPL_TIME(F("%sysmin%"), PSTR("%02d"), minute())
|
||||
SMART_REPL_TIME(F("%syssec%"),PSTR("%02d"), second())
|
||||
SMART_REPL_TIME(F("%syssec_d%"),PSTR("%d"), ((hour()*60) + minute())*60 + second());
|
||||
SMART_REPL_TIME(F("%sysday%"), PSTR("%02d"), day())
|
||||
SMART_REPL_TIME(F("%sysmonth%"),PSTR("%02d"), month())
|
||||
SMART_REPL_TIME(F("%sysyear%"), PSTR("%04d"), year())
|
||||
|
||||
+734
-705
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_C001
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 001: Domoticz HTTP ######################################
|
||||
//#######################################################################################################
|
||||
@@ -165,3 +166,4 @@ boolean CPlugin_001(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_C002
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 002: Domoticz MQTT ######################################
|
||||
//#######################################################################################################
|
||||
@@ -209,3 +210,4 @@ boolean CPlugin_002(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_C003
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 003: Nodo Telnet #######################################
|
||||
//#######################################################################################################
|
||||
@@ -107,3 +108,4 @@ boolean CPlugin_003(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_C004
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 004: ThingSpeak #########################################
|
||||
//#######################################################################################################
|
||||
@@ -127,3 +128,4 @@ boolean CPlugin_004(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_C005
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 005: OpenHAB MQTT #######################################
|
||||
//#######################################################################################################
|
||||
@@ -122,3 +123,4 @@ boolean CPlugin_005(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_C006
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 006: PiDome MQTT ########################################
|
||||
//#######################################################################################################
|
||||
@@ -109,3 +110,4 @@ boolean CPlugin_006(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_C007
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 007: Emoncms ############################################
|
||||
//#######################################################################################################
|
||||
@@ -122,3 +123,4 @@ boolean CPlugin_007(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_C008
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 008: Generic HTTP #######################################
|
||||
//#######################################################################################################
|
||||
@@ -151,3 +152,4 @@ boolean HTTPSend(struct EventStruct *event, byte varIndex, float value, unsigned
|
||||
|
||||
return(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_C009
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 009: FHEM HTTP ##########################################
|
||||
//#######################################################################################################
|
||||
@@ -197,3 +198,4 @@ void FHEMHTTPsend(String & url, String & buffer, byte index)
|
||||
client.flush();
|
||||
client.stop();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_C010
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 010: Generic UDP ########################################
|
||||
//#######################################################################################################
|
||||
@@ -97,3 +98,4 @@ void C010_Send(struct EventStruct *event, byte varIndex, float value, unsigned l
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
+3
-1
@@ -1,8 +1,9 @@
|
||||
#ifdef USES_C011
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 011: Generic HTTP #######################################
|
||||
//#######################################################################################################
|
||||
|
||||
#ifdef PLUGIN_BUILD_TESTING
|
||||
// #ifdef PLUGIN_BUILD_TESTING
|
||||
|
||||
#define CPLUGIN_011
|
||||
#define CPLUGIN_ID_011 11
|
||||
@@ -283,3 +284,4 @@ void ReplaceTokenByValue(String& s, struct EventStruct *event)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
#ifdef USES_C012
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 012: Blynk #############################################
|
||||
//#######################################################################################################
|
||||
|
||||
#ifdef PLUGIN_BUILD_TESTING
|
||||
// #ifdef PLUGIN_BUILD_TESTING
|
||||
|
||||
#define CPLUGIN_012
|
||||
#define CPLUGIN_ID_012 12
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_C013
|
||||
//#######################################################################################################
|
||||
//########################### Controller Plugin 013: ESPEasy P2P network ################################
|
||||
//#######################################################################################################
|
||||
@@ -262,4 +263,4 @@ void C013_Receive(struct EventStruct *event) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_N001
|
||||
//#######################################################################################################
|
||||
//########################### Notification Plugin 001: Email ############################################
|
||||
//#######################################################################################################
|
||||
@@ -174,3 +175,4 @@ boolean NPlugin_001_MTA(WiFiClient& client, String aStr, const String &aWaitForP
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef USES_N002
|
||||
//#######################################################################################################
|
||||
//########################### Notification Plugin 002: Buzzer ###########################################
|
||||
//#######################################################################################################
|
||||
@@ -56,3 +57,4 @@ boolean NPlugin_002(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -69,13 +69,13 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
|
||||
options[1] = F("Dimmer");
|
||||
int optionValues[2] = { PLUGIN_001_TYPE_SWITCH, PLUGIN_001_TYPE_DIMMER };
|
||||
const byte switchtype = P001_getSwitchType(event);
|
||||
addFormSelector(string, F("Switch Type"), F("plugin_001_type"), 2, options, optionValues, switchtype);
|
||||
addFormSelector(F("Switch Type"), F("plugin_001_type"), 2, options, optionValues, switchtype);
|
||||
|
||||
if (switchtype == PLUGIN_001_TYPE_DIMMER)
|
||||
{
|
||||
char tmpString[128];
|
||||
sprintf_P(tmpString, PSTR("<TR><TD>Dim value:<TD><input type='text' name='plugin_001_dimvalue' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
string += tmpString;
|
||||
addHtml(tmpString);
|
||||
}
|
||||
|
||||
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
|
||||
@@ -84,9 +84,9 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
|
||||
buttonOptions[1] = F("Push Button Active Low");
|
||||
buttonOptions[2] = F("Push Button Active High");
|
||||
int buttonOptionValues[3] = {PLUGIN_001_BUTTON_TYPE_NORMAL_SWITCH, PLUGIN_001_BUTTON_TYPE_PUSH_ACTIVE_LOW, PLUGIN_001_BUTTON_TYPE_PUSH_ACTIVE_HIGH};
|
||||
addFormSelector(string, F("Switch Button Type"), F("plugin_001_button"), 3, buttonOptions, buttonOptionValues, choice);
|
||||
addFormSelector(F("Switch Button Type"), F("plugin_001_button"), 3, buttonOptions, buttonOptionValues, choice);
|
||||
|
||||
addFormCheckBox(string, F("Send Boot state"),F("plugin_001_boot"),
|
||||
addFormCheckBox(F("Send Boot state"),F("plugin_001_boot"),
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
|
||||
success = true;
|
||||
@@ -149,7 +149,7 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case PLUGIN_UNCONDITIONAL_POLL:
|
||||
{
|
||||
// port monitoring, on request by rule command
|
||||
|
||||
+12
-12
@@ -49,23 +49,23 @@ boolean Plugin_002(byte function, struct EventStruct *event, String& string)
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
#if defined(ESP32)
|
||||
string += F("<TR><TD>Analog Pin:<TD>");
|
||||
addPinSelect(false, string, "taskdevicepin1", Settings.TaskDevicePin1[event->TaskIndex]);
|
||||
addHtml(F("<TR><TD>Analog Pin:<TD>"));
|
||||
addPinSelect(false, "taskdevicepin1", Settings.TaskDevicePin1[event->TaskIndex]);
|
||||
#endif
|
||||
|
||||
addFormCheckBox(string, F("Oversampling"), F("plugin_002_oversampling"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
|
||||
addFormSubHeader(string, F("Two Point Calibration"));
|
||||
addFormCheckBox(F("Oversampling"), F("plugin_002_oversampling"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
|
||||
addFormCheckBox(string, F("Calibration Enabled"), F("plugin_002_cal"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
addFormSubHeader(F("Two Point Calibration"));
|
||||
|
||||
addFormNumericBox(string, F("Point 1"), F("plugin_002_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], 0, 1023);
|
||||
string += F(" ≙ ");
|
||||
addTextBox(string, F("plugin_002_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
|
||||
addFormCheckBox(F("Calibration Enabled"), F("plugin_002_cal"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
|
||||
addFormNumericBox(string, F("Point 2"), F("plugin_002_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], 0, 1023);
|
||||
string += F(" ≙ ");
|
||||
addTextBox(string, F("plugin_002_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
|
||||
addFormNumericBox(F("Point 1"), F("plugin_002_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], 0, 1023);
|
||||
addHtml(F(" ≙ "));
|
||||
addTextBox(F("plugin_002_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
|
||||
|
||||
addFormNumericBox(F("Point 2"), F("plugin_002_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], 0, 1023);
|
||||
addHtml(F(" ≙ "));
|
||||
addTextBox(F("plugin_002_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+4
-4
@@ -65,16 +65,16 @@ boolean Plugin_003(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormNumericBox(string, F("Debounce Time (mSec)"), F("plugin_003")
|
||||
addFormNumericBox(F("Debounce Time (mSec)"), F("plugin_003")
|
||||
, Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
|
||||
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
|
||||
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
|
||||
String options[4] = { F("Delta"), F("Delta/Total/Time"), F("Total"), F("Delta/Total") };
|
||||
addFormSelector(string, F("Counter Type"), F("plugin_003_countertype"), 4, options, NULL, choice );
|
||||
addFormSelector(F("Counter Type"), F("plugin_003_countertype"), 4, options, NULL, choice );
|
||||
|
||||
if (choice !=0)
|
||||
string += F("<span style=\"color:red\">Total count is not persistent!</span>");
|
||||
addHtml(F("<span style=\"color:red\">Total count is not persistent!</span>"));
|
||||
|
||||
String modeRaise[4];
|
||||
modeRaise[0] = F("LOW");
|
||||
@@ -87,7 +87,7 @@ boolean Plugin_003(byte function, struct EventStruct *event, String& string)
|
||||
modeValues[2] = RISING;
|
||||
modeValues[3] = FALLING;
|
||||
|
||||
addFormSelector(string, F("Mode Type"), F("plugin_003_raisetype"), 4, modeRaise, modeValues, choice2 );
|
||||
addFormSelector(F("Mode Type"), F("plugin_003_raisetype"), 4, modeRaise, modeValues, choice2 );
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+12
-8
@@ -64,9 +64,9 @@ boolean Plugin_004(byte function, struct EventStruct * event, String& string)
|
||||
savedAddress[i] = ExtraTaskSettings.TaskDevicePluginConfigLong[i];
|
||||
|
||||
// find all suitable devices
|
||||
addRowLabel(string, F("Device Address"));
|
||||
addSelector_Head(string, F("plugin_004_dev"), false);
|
||||
addSelector_Item(string, "", -1, false, false, F(""));
|
||||
addRowLabel(F("Device Address"));
|
||||
addSelector_Head(F("plugin_004_dev"), false);
|
||||
addSelector_Item("", -1, false, false, F(""));
|
||||
uint8_t tmpAddress[8];
|
||||
byte count = 0;
|
||||
Plugin_004_DS_reset();
|
||||
@@ -80,10 +80,10 @@ boolean Plugin_004(byte function, struct EventStruct * event, String& string)
|
||||
if (j < 7) option += F("-");
|
||||
}
|
||||
bool selected = (memcmp(tmpAddress, savedAddress, 8) == 0) ? true : false;
|
||||
addSelector_Item(string, option, count, selected, false, F(""));
|
||||
addSelector_Item(option, count, selected, false, F(""));
|
||||
count ++;
|
||||
}
|
||||
addSelector_Foot(string);
|
||||
addSelector_Foot();
|
||||
|
||||
// Device Resolution select
|
||||
if (ExtraTaskSettings.TaskDevicePluginConfigLong[0] != 0)
|
||||
@@ -92,8 +92,8 @@ boolean Plugin_004(byte function, struct EventStruct * event, String& string)
|
||||
resolutionChoice = 9;
|
||||
String resultsOptions[4] = { "9", "10", "11", "12" };
|
||||
int resultsOptionValues[4] = { 9, 10, 11, 12 };
|
||||
addFormSelector(string, F("Device Resolution"), F("plugin_004_res"), 4, resultsOptions, resultsOptionValues, resolutionChoice);
|
||||
string += F(" Bit");
|
||||
addFormSelector(F("Device Resolution"), F("plugin_004_res"), 4, resultsOptions, resultsOptionValues, resolutionChoice);
|
||||
addHtml(F(" Bit"));
|
||||
}
|
||||
success = true;
|
||||
break;
|
||||
@@ -251,13 +251,17 @@ boolean Plugin_004_DS_readTemp(uint8_t ROM[8], float * value)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((ROM[0] == 0x28 ) || (ROM[0] == 0x3b)) // DS18B20 or DS1825
|
||||
if ((ROM[0] == 0x28 ) || (ROM[0] == 0x3b) || (ROM[0] == 0x22)) // DS18B20 or DS1825 or DS1822
|
||||
{
|
||||
DSTemp = (ScratchPad[1] << 8) + ScratchPad[0];
|
||||
if (DSTemp == 0x550) // power-on reset value
|
||||
return false;
|
||||
*value = (float(DSTemp) * 0.0625);
|
||||
}
|
||||
else if (ROM[0] == 0x10) // DS1820 DS18S20
|
||||
{
|
||||
if (ScratchPad[0] == 0xaa) // power-on reset value
|
||||
return false;
|
||||
DSTemp = (ScratchPad[1] << 11) | ScratchPad[0] << 3;
|
||||
DSTemp = ((DSTemp & 0xfff0) << 3) - 16 +
|
||||
(((ScratchPad[7] - ScratchPad[6]) << 7) / ScratchPad[7]);
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ boolean Plugin_005(byte function, struct EventStruct *event, String& string)
|
||||
const String options[] = { F("DHT 11"), F("DHT 22"), F("DHT 12"), F("Sonoff am2301"), F("Sonoff si7021") };
|
||||
int indices[] = { 11, 22, 12, 23, 70 };
|
||||
|
||||
addFormSelector(string, F("DHT Type"), F("plugin_005_dhttype"), 5, options, indices, Settings.TaskDevicePluginConfig[event->TaskIndex][0] );
|
||||
addFormSelector(F("DHT Type"), F("plugin_005_dhttype"), 5, options, indices, Settings.TaskDevicePluginConfig[event->TaskIndex][0] );
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -50,7 +50,7 @@ boolean Plugin_006(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormNumericBox(string, F("Altitude [m]"), F("_p006_bmp085_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addFormNumericBox(F("Altitude [m]"), F("_p006_bmp085_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ boolean Plugin_009(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormCheckBox(string, F("Send Boot state") ,F("plugin_009_boot"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
addFormCheckBox(F("Send Boot state") ,F("plugin_009_boot"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -57,8 +57,8 @@ boolean Plugin_010(byte function, struct EventStruct *event, String& string)
|
||||
int optionValues[2];
|
||||
optionValues[0] = BH1750_DEFAULT_I2CADDR;
|
||||
optionValues[1] = BH1750_SECOND_I2CADDR;
|
||||
addFormSelectorI2C(string, F("plugin_010"), 2, optionValues, choice);
|
||||
addFormNote(string, F("ADDR Low=0x23, High=0x5c"));
|
||||
addFormSelectorI2C(F("plugin_010"), 2, optionValues, choice);
|
||||
addFormNote(F("ADDR Low=0x23, High=0x5c"));
|
||||
|
||||
byte choiceMode = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
|
||||
String optionsMode[4];
|
||||
@@ -71,9 +71,9 @@ boolean Plugin_010(byte function, struct EventStruct *event, String& string)
|
||||
optionValuesMode[1] = RESOLUTION_NORMAL;
|
||||
optionValuesMode[2] = RESOLUTION_HIGH;
|
||||
optionValuesMode[3] = RESOLUTION_AUTO_HIGH;
|
||||
addFormSelector(string, F("Measurement mode"), F("plugin_010_mode"), 4, optionsMode, optionValuesMode, choiceMode);
|
||||
addFormSelector(F("Measurement mode"), F("plugin_010_mode"), 4, optionsMode, optionValuesMode, choiceMode);
|
||||
|
||||
addFormCheckBox(string, F("Send sensor to sleep"), F("plugin_010_sleep"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
addFormCheckBox(F("Send sensor to sleep"), F("plugin_010_sleep"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ boolean Plugin_011(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
|
||||
String options[2] = { F("Digital"), F("Analog") };
|
||||
addFormSelector(string, F("Port Type"), F("plugin_011"), 2, options, NULL, choice);
|
||||
addFormSelector(F("Port Type"), F("plugin_011"), 2, options, NULL, choice);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+13
-13
@@ -67,7 +67,7 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
|
||||
//options[x] = F("0x");
|
||||
//options[x] += String(optionValues[x], HEX);
|
||||
}
|
||||
addFormSelectorI2C(string, F("plugin_012_adr"), 16, optionValues, choice);
|
||||
addFormSelectorI2C(F("plugin_012_adr"), 16, optionValues, choice);
|
||||
|
||||
|
||||
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
|
||||
@@ -75,30 +75,30 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
|
||||
options2[0] = F("2 x 16");
|
||||
options2[1] = F("4 x 20");
|
||||
int optionValues2[2] = { 1, 2 };
|
||||
addFormSelector(string, F("Display Size"), F("plugin_012_size"), 2, options2, optionValues2, choice2);
|
||||
addFormSelector(F("Display Size"), F("plugin_012_size"), 2, options2, optionValues2, choice2);
|
||||
|
||||
|
||||
char deviceTemplate[4][80];
|
||||
LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
|
||||
for (byte varNr = 0; varNr < 4; varNr++)
|
||||
{
|
||||
string += F("<TR><TD>Line ");
|
||||
string += varNr + 1;
|
||||
string += F(":<TD><input type='text' size='80' maxlength='80' name='Plugin_012_template");
|
||||
string += varNr + 1;
|
||||
string += F("' value='");
|
||||
string += deviceTemplate[varNr];
|
||||
string += F("'>");
|
||||
addHtml(F("<TR><TD>Line "));
|
||||
addHtml(String(varNr + 1));
|
||||
addHtml(F(":<TD><input type='text' size='80' maxlength='80' name='Plugin_012_template"));
|
||||
addHtml(String(varNr + 1));
|
||||
addHtml(F("' value='"));
|
||||
addHtml(deviceTemplate[varNr]);
|
||||
addHtml(F("'>"));
|
||||
}
|
||||
|
||||
|
||||
addRowLabel(string, "Display button");
|
||||
addPinSelect(false, string, "taskdevicepin3", Settings.TaskDevicePin3[event->TaskIndex]);
|
||||
addRowLabel("Display button");
|
||||
addPinSelect(false, "taskdevicepin3", Settings.TaskDevicePin3[event->TaskIndex]);
|
||||
|
||||
|
||||
char tmpString[128];
|
||||
sprintf_P(tmpString, PSTR("<TR><TD>Display Timeout:<TD><input type='text' name='plugin_12_timer' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
string += tmpString;
|
||||
addHtml(tmpString);
|
||||
|
||||
|
||||
String options3[3];
|
||||
@@ -106,7 +106,7 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
|
||||
options3[1] = F("Truncate exceeding message");
|
||||
options3[2] = F("Clear then truncate exceeding message");
|
||||
int optionValues3[3] = { 0,1,2 };
|
||||
addFormSelector(string, F("LCD command Mode"), F("plugin_012_mode"), 3, options3, optionValues3, Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
addFormSelector(F("LCD command Mode"), F("plugin_012_mode"), 3, options3, optionValues3, Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+33
-45
@@ -1,20 +1,19 @@
|
||||
#ifdef USES_P013
|
||||
//#######################################################################################################
|
||||
//#################################### Plugin 013: HC-SR04 ##############################################
|
||||
//############################### Plugin 013: HC-SR04, RCW-0001, etc. ###################################
|
||||
//#######################################################################################################
|
||||
|
||||
#define PLUGIN_013
|
||||
#define PLUGIN_ID_013 13
|
||||
#define PLUGIN_NAME_013 "Distance - HC-SR04"
|
||||
#define PLUGIN_NAME_013 "Distance - HC-SR04, RCW-0001, etc."
|
||||
#define PLUGIN_VALUENAME1_013 "Distance"
|
||||
|
||||
void Plugin_013_interrupt() ICACHE_RAM_ATTR;
|
||||
#include <NewPing.h>
|
||||
|
||||
boolean Plugin_013_init = false;
|
||||
volatile unsigned long Plugin_013_timer = 0;
|
||||
volatile unsigned long Plugin_013_state = 0;
|
||||
byte Plugin_013_TRIG_Pin = 0;
|
||||
byte Plugin_013_IRQ_Pin = 0;
|
||||
NewPing *sonar = NULL;
|
||||
|
||||
boolean Plugin_013(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
@@ -59,11 +58,11 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
|
||||
options[0] = F("Value");
|
||||
options[1] = F("State");
|
||||
int optionValues[2] = { 1, 2 };
|
||||
addFormSelector(string, F("Mode"), F("plugin_013_mode"), 2, options, optionValues, choice);
|
||||
addFormSelector(F("Mode"), F("plugin_013_mode"), 2, options, optionValues, choice);
|
||||
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 2)
|
||||
{
|
||||
addFormNumericBox(string, F("Threshold"), F("plugin_013_threshold"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addFormNumericBox(F("Threshold"), F("plugin_013_threshold"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
}
|
||||
success = true;
|
||||
break;
|
||||
@@ -83,21 +82,38 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
|
||||
case PLUGIN_INIT:
|
||||
{
|
||||
Plugin_013_init = true;
|
||||
pinMode(Settings.TaskDevicePin1[event->TaskIndex], OUTPUT);
|
||||
pinMode(Settings.TaskDevicePin2[event->TaskIndex], INPUT_PULLUP);
|
||||
|
||||
Plugin_013_TRIG_Pin = Settings.TaskDevicePin1[event->TaskIndex];
|
||||
Plugin_013_IRQ_Pin = Settings.TaskDevicePin2[event->TaskIndex];
|
||||
attachInterrupt(Settings.TaskDevicePin2[event->TaskIndex], Plugin_013_interrupt, CHANGE);
|
||||
|
||||
if (sonar)
|
||||
{
|
||||
delete sonar;
|
||||
sonar=NULL;
|
||||
}
|
||||
|
||||
sonar = new NewPing(Plugin_013_TRIG_Pin, Plugin_013_IRQ_Pin);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_EXIT:
|
||||
{
|
||||
if (sonar)
|
||||
{
|
||||
delete sonar;
|
||||
sonar=NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_READ: // If we select value mode, read and send the value based on global timer
|
||||
{
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 1)
|
||||
{
|
||||
Plugin_013_TRIG_Pin = Settings.TaskDevicePin1[event->TaskIndex];
|
||||
float value = Plugin_013_read();
|
||||
String log = F("SR04 : Distance: ");
|
||||
String log = F("ULTRASONIC : Distance: ");
|
||||
if (value > 0)
|
||||
{
|
||||
UserVar[event->BaseVarIndex] = value;
|
||||
@@ -125,7 +141,7 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
|
||||
state = 1;
|
||||
if (state != switchstate[event->TaskIndex])
|
||||
{
|
||||
String log = F("SR04 : State ");
|
||||
String log = F("ULTRASONIC : State ");
|
||||
log += state;
|
||||
addLog(LOG_LEVEL_INFO,log);
|
||||
switchstate[event->TaskIndex] = state;
|
||||
@@ -146,39 +162,11 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
|
||||
float Plugin_013_read()
|
||||
/*********************************************************************/
|
||||
{
|
||||
float value = -1;
|
||||
Plugin_013_timer = 0;
|
||||
Plugin_013_state = 0;
|
||||
noInterrupts();
|
||||
digitalWrite(Plugin_013_TRIG_Pin, LOW);
|
||||
delayMicroseconds(2);
|
||||
digitalWrite(Plugin_013_TRIG_Pin, HIGH);
|
||||
delayMicroseconds(10);
|
||||
digitalWrite(Plugin_013_TRIG_Pin, LOW);
|
||||
interrupts();
|
||||
if (!sonar)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
delay(25); // wait for measurement to finish (max 400 cm * 58 uSec = 23uSec)
|
||||
if (Plugin_013_state == 2)
|
||||
{
|
||||
value = (float)Plugin_013_timer / 58;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
void Plugin_013_interrupt()
|
||||
/*********************************************************************/
|
||||
{
|
||||
byte pinState = digitalRead(Plugin_013_IRQ_Pin);
|
||||
if (pinState == 1) // Start of pulse
|
||||
{
|
||||
Plugin_013_state = 1;
|
||||
Plugin_013_timer = micros();
|
||||
}
|
||||
else // End of pulse, calculate timelapse between start & end
|
||||
{
|
||||
Plugin_013_state = 2;
|
||||
Plugin_013_timer = micros() - Plugin_013_timer;
|
||||
}
|
||||
return sonar->ping_cm();
|
||||
}
|
||||
#endif // USES_P013
|
||||
|
||||
@@ -86,8 +86,8 @@ boolean Plugin_014(byte function, struct EventStruct *event, String& string)
|
||||
options[2] = F("Temp 12 bits / RH 8 bits");
|
||||
optionValues[3] = SI7021_RESOLUTION_11T_11RH;
|
||||
options[3] = F("Temp 11 bits / RH 11 bits");
|
||||
addFormSelector(string, F("Resolution"), F("plugin_014_res"), SI7021_RESOLUTION_OPTION, options, optionValues, choice);
|
||||
//addUnit(string, F("bits"));
|
||||
addFormSelector(F("Resolution"), F("plugin_014_res"), SI7021_RESOLUTION_OPTION, options, optionValues, choice);
|
||||
//addUnit(F("bits"));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+26
-9
@@ -12,6 +12,8 @@
|
||||
#define PLUGIN_ID_015 15
|
||||
#define PLUGIN_NAME_015 "Light/Lux - TSL2561"
|
||||
#define PLUGIN_VALUENAME1_015 "Lux"
|
||||
#define PLUGIN_VALUENAME2_015 "Infrared"
|
||||
#define PLUGIN_VALUENAME3_015 "Broadband"
|
||||
|
||||
boolean Plugin_015_init = false;
|
||||
|
||||
@@ -219,7 +221,7 @@ boolean plugin_015_getData(unsigned int &data0, unsigned int &data1)
|
||||
}
|
||||
|
||||
|
||||
boolean plugin_015_getLux(unsigned char gain, unsigned int ms, unsigned int CH0, unsigned int CH1, double &lux)
|
||||
boolean plugin_015_getLux(unsigned char gain, unsigned int ms, unsigned int CH0, unsigned int CH1, double &lux, double &infrared, double &broadband)
|
||||
// Convert raw data to lux
|
||||
// gain: 0 (1X) or 1 (16X), see setTiming()
|
||||
// ms: integration time in ms, from setTiming() or from manual integration
|
||||
@@ -246,6 +248,10 @@ boolean plugin_015_getLux(unsigned char gain, unsigned int ms, unsigned int CH0,
|
||||
// We will need the ratio for subsequent calculations
|
||||
ratio = d1 / d0;
|
||||
|
||||
// save original values
|
||||
infrared = d1;
|
||||
broadband = d0;
|
||||
|
||||
// Normalize for integration time
|
||||
d0 *= (402.0/ms);
|
||||
d1 *= (402.0/ms);
|
||||
@@ -290,7 +296,6 @@ boolean plugin_015_getLux(unsigned char gain, unsigned int ms, unsigned int CH0,
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean Plugin_015(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
boolean success = false;
|
||||
@@ -301,12 +306,12 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
Device[++deviceCount].Number = PLUGIN_ID_015;
|
||||
Device[deviceCount].Type = DEVICE_TYPE_I2C;
|
||||
Device[deviceCount].VType = SENSOR_TYPE_SINGLE;
|
||||
Device[deviceCount].VType = SENSOR_TYPE_TRIPLE;
|
||||
Device[deviceCount].Ports = 0;
|
||||
Device[deviceCount].PullUpOption = false;
|
||||
Device[deviceCount].InverseLogicOption = false;
|
||||
Device[deviceCount].FormulaOption = true;
|
||||
Device[deviceCount].ValueCount = 1;
|
||||
Device[deviceCount].ValueCount = 3;
|
||||
Device[deviceCount].SendDataOption = true;
|
||||
Device[deviceCount].TimerOption = true;
|
||||
Device[deviceCount].GlobalSyncOption = true;
|
||||
@@ -322,6 +327,9 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
|
||||
case PLUGIN_GET_DEVICEVALUENAMES:
|
||||
{
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_015));
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_015));
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_015));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -338,7 +346,7 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
|
||||
optionValues1[0] = TSL2561_ADDR;
|
||||
optionValues1[1] = TSL2561_ADDR_1;
|
||||
optionValues1[2] = TSL2561_ADDR_0;
|
||||
addFormSelectorI2C(string, F("plugin_015_tsl2561_i2c"), 3, optionValues1, choice1);
|
||||
addFormSelectorI2C(F("plugin_015_tsl2561_i2c"), 3, optionValues1, choice1);
|
||||
|
||||
#define TSL2561_INTEGRATION_OPTION 3
|
||||
|
||||
@@ -351,12 +359,12 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
|
||||
options2[1] = F("101 ms");
|
||||
optionValues2[2] = 0x02;
|
||||
options2[2] = F("402 ms");
|
||||
addFormSelector(string, F("Integration time"), F("plugin_015_integration"), TSL2561_INTEGRATION_OPTION, options2, optionValues2, choice2);
|
||||
addFormSelector(F("Integration time"), F("plugin_015_integration"), TSL2561_INTEGRATION_OPTION, options2, optionValues2, choice2);
|
||||
|
||||
addFormCheckBox(string, F("Send sensor to sleep:"), F("plugin_015_sleep"),
|
||||
addFormCheckBox(F("Send sensor to sleep:"), F("plugin_015_sleep"),
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
|
||||
addFormCheckBox(string, F("Enable 16x Gain:"), F("plugin_015_gain"),
|
||||
addFormCheckBox(F("Enable 16x Gain:"), F("plugin_015_gain"),
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
|
||||
success = true;
|
||||
@@ -403,12 +411,17 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
|
||||
double lux; // Resulting lux value
|
||||
double infrared; // Resulting infrared value
|
||||
double broadband; // Resulting broadband value
|
||||
boolean good; // True if neither sensor is saturated
|
||||
|
||||
// Perform lux calculation:
|
||||
|
||||
good = plugin_015_getLux(gain,ms,data0,data1,lux);
|
||||
good = plugin_015_getLux(gain,ms,data0,data1,lux, infrared, broadband);
|
||||
UserVar[event->BaseVarIndex] = lux;
|
||||
UserVar[event->BaseVarIndex + 1] = infrared;
|
||||
UserVar[event->BaseVarIndex + 2] = broadband;
|
||||
|
||||
if (!good)
|
||||
{
|
||||
addLog(LOG_LEVEL_INFO,F("TSL2561: Sensor saturated! > 65535 Lux"));
|
||||
@@ -423,6 +436,10 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
|
||||
log += String(gain,HEX);
|
||||
log += F(": Lux: ");
|
||||
log += UserVar[event->BaseVarIndex];
|
||||
log += F(": Infrared: ");
|
||||
log += UserVar[event->BaseVarIndex + 1];
|
||||
log += F(": Broadband: ");
|
||||
log += UserVar[event->BaseVarIndex + 2];
|
||||
addLog(LOG_LEVEL_INFO,log);
|
||||
}
|
||||
else
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ boolean Plugin_017(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormPinSelect(string, F("Reset Pin"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
|
||||
addFormPinSelect(F("Reset Pin"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ boolean Plugin_019(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormCheckBox(string, F("Send Boot state"), F("plugin_019_boot"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
addFormCheckBox(F("Send Boot state"), F("plugin_019_boot"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -46,9 +46,9 @@ boolean Plugin_020(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormNumericBox(string, F("TCP Port"), F("plugin_020_port"), ExtraTaskSettings.TaskDevicePluginConfigLong[0]);
|
||||
addFormNumericBox(string, F("Baud Rate"), F("plugin_020_baud"), ExtraTaskSettings.TaskDevicePluginConfigLong[1]);
|
||||
addFormNumericBox(string, F("Data bits"), F("plugin_020_data"), ExtraTaskSettings.TaskDevicePluginConfigLong[2]);
|
||||
addFormNumericBox(F("TCP Port"), F("plugin_020_port"), ExtraTaskSettings.TaskDevicePluginConfigLong[0]);
|
||||
addFormNumericBox(F("Baud Rate"), F("plugin_020_baud"), ExtraTaskSettings.TaskDevicePluginConfigLong[1]);
|
||||
addFormNumericBox(F("Data bits"), F("plugin_020_data"), ExtraTaskSettings.TaskDevicePluginConfigLong[2]);
|
||||
|
||||
byte choice = ExtraTaskSettings.TaskDevicePluginConfigLong[3];
|
||||
String options[3];
|
||||
@@ -59,13 +59,13 @@ boolean Plugin_020(byte function, struct EventStruct *event, String& string)
|
||||
optionValues[0] = 0;
|
||||
optionValues[1] = 2;
|
||||
optionValues[2] = 3;
|
||||
addFormSelector(string, F("Parity"), F("plugin_020_parity"), 3, options, optionValues, choice);
|
||||
addFormSelector(F("Parity"), F("plugin_020_parity"), 3, options, optionValues, choice);
|
||||
|
||||
addFormNumericBox(string, F("Stop bits"), F("plugin_020_stop"), ExtraTaskSettings.TaskDevicePluginConfigLong[4]);
|
||||
addFormNumericBox(F("Stop bits"), F("plugin_020_stop"), ExtraTaskSettings.TaskDevicePluginConfigLong[4]);
|
||||
|
||||
addFormPinSelect(string, F("Reset target after boot"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]);
|
||||
addFormPinSelect(F("Reset target after boot"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]);
|
||||
|
||||
addFormNumericBox(string, F("RX Receive Timeout (mSec)"), F("plugin_020_rxwait"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
addFormNumericBox(F("RX Receive Timeout (mSec)"), F("plugin_020_rxwait"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
|
||||
|
||||
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
|
||||
@@ -73,7 +73,7 @@ boolean Plugin_020(byte function, struct EventStruct *event, String& string)
|
||||
options2[0] = F("None");
|
||||
options2[1] = F("Generic");
|
||||
options2[2] = F("RFLink");
|
||||
addFormSelector(string, F("Event processing"), F("plugin_020_events"), 3, options2, NULL, choice2);
|
||||
addFormSelector(F("Event processing"), F("plugin_020_events"), 3, options2, NULL, choice2);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+6
-6
@@ -47,16 +47,16 @@ boolean Plugin_021(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
// char tmpString[128];
|
||||
|
||||
string += F("<TR><TD>Check Task:<TD>");
|
||||
addTaskSelect(string, "plugin_021_task", Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
addHtml(F("<TR><TD>Check Task:<TD>"));
|
||||
addTaskSelect("plugin_021_task", Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
|
||||
LoadTaskSettings(Settings.TaskDevicePluginConfig[event->TaskIndex][0]); // we need to load the values from another task for selection!
|
||||
string += F("<TR><TD>Check Value:<TD>");
|
||||
addTaskValueSelect(string, "plugin_021_value", Settings.TaskDevicePluginConfig[event->TaskIndex][1], Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
addHtml(F("<TR><TD>Check Value:<TD>"));
|
||||
addTaskValueSelect("plugin_021_value", Settings.TaskDevicePluginConfig[event->TaskIndex][1], Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
|
||||
addFormTextBox(string, F("Set Level"), F("plugin_021_setvalue"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0]), 8);
|
||||
addFormTextBox(F("Set Level"), F("plugin_021_setvalue"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0]), 8);
|
||||
|
||||
addFormTextBox(string, F("Hysteresis"), F("plugin_021_hyst"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1]), 8);
|
||||
addFormTextBox(F("Hysteresis"), F("plugin_021_hyst"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1]), 8);
|
||||
|
||||
LoadTaskSettings(event->TaskIndex); // we need to restore our original taskvalues!
|
||||
success = true;
|
||||
|
||||
+7
-7
@@ -71,33 +71,33 @@ boolean Plugin_023(byte function, struct EventStruct *event, String& string)
|
||||
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
|
||||
/*String options[2] = { F("3C"), F("3D") };*/
|
||||
int optionValues[2] = { 0x3C, 0x3D };
|
||||
addFormSelectorI2C(string, F("plugin_023_adr"), 2, optionValues, choice);
|
||||
addFormSelectorI2C(F("plugin_023_adr"), 2, optionValues, choice);
|
||||
|
||||
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
|
||||
String options2[2] = { F("Normal"), F("Rotated") };
|
||||
int optionValues2[2] = { 1, 2 };
|
||||
addFormSelector(string, F("Rotation"), F("plugin_023_rotate"), 2, options2, optionValues2, choice2);
|
||||
addFormSelector(F("Rotation"), F("plugin_023_rotate"), 2, options2, optionValues2, choice2);
|
||||
|
||||
byte choice3 = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
|
||||
String options3[3] = { F("128x64"), F("128x32"), F("64x48") };
|
||||
int optionValues3[3] = { 1, 3, 2 };
|
||||
addFormSelector(string, F("Display Size"), F("plugin_023_size"), 3, options3, optionValues3, choice3);
|
||||
addFormSelector(F("Display Size"), F("plugin_023_size"), 3, options3, optionValues3, choice3);
|
||||
|
||||
byte choice4 = Settings.TaskDevicePluginConfig[event->TaskIndex][4];
|
||||
String options4[2] = { F("Normal"), F("Optimized") };
|
||||
int optionValues4[2] = { 1, 2 };
|
||||
addFormSelector(string, F("Font Width"), F("plugin_023_font_width"), 2, options4, optionValues4, choice4);
|
||||
addFormSelector(F("Font Width"), F("plugin_023_font_width"), 2, options4, optionValues4, choice4);
|
||||
|
||||
char deviceTemplate[8][64];
|
||||
LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
|
||||
for (byte varNr = 0; varNr < 8; varNr++)
|
||||
{
|
||||
addFormTextBox(string, String(F("Line ")) + (varNr + 1), String(F("Plugin_023_template")) + (varNr + 1), deviceTemplate[varNr], 64);
|
||||
addFormTextBox(String(F("Line ")) + (varNr + 1), String(F("Plugin_023_template")) + (varNr + 1), deviceTemplate[varNr], 64);
|
||||
}
|
||||
|
||||
addFormPinSelect(string, F("Display button"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
|
||||
addFormPinSelect(F("Display button"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
|
||||
|
||||
addFormNumericBox(string, F("Display Timeout"), F("plugin_23_timer"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
addFormNumericBox(F("Display Timeout"), F("plugin_23_timer"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -78,7 +78,7 @@ boolean Plugin_024(byte function, struct EventStruct *event, String& string)
|
||||
options[0] = F("IR object temperature");
|
||||
optionValues[1] = (0x06);
|
||||
options[1] = F("Ambient temperature");
|
||||
addFormSelector(string, F("Option"), F("plugin_024_option"), MLX90614_OPTION, options, optionValues, choice);
|
||||
addFormSelector(F("Option"), F("plugin_024_option"), MLX90614_OPTION, options, optionValues, choice);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+12
-12
@@ -67,9 +67,9 @@ boolean Plugin_025(byte function, struct EventStruct *event, String& string)
|
||||
#define ADS1115_I2C_OPTION 4
|
||||
byte addr = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
|
||||
int optionValues[ADS1115_I2C_OPTION] = { 0x48, 0x49, 0x4A, 0x4B };
|
||||
addFormSelectorI2C(string, F("plugin_025_i2c"), ADS1115_I2C_OPTION, optionValues, addr);
|
||||
addFormSelectorI2C(F("plugin_025_i2c"), ADS1115_I2C_OPTION, optionValues, addr);
|
||||
|
||||
addFormSubHeader(string, F("Input"));
|
||||
addFormSubHeader(F("Input"));
|
||||
|
||||
#define ADS1115_PGA_OPTION 6
|
||||
byte pga = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
|
||||
@@ -81,7 +81,7 @@ boolean Plugin_025(byte function, struct EventStruct *event, String& string)
|
||||
F("8x gain (FS=0.512V)"),
|
||||
F("16x gain (FS=0.256V)")
|
||||
};
|
||||
addFormSelector(string, F("Gain"), F("plugin_025_gain"), ADS1115_PGA_OPTION, pgaOptions, NULL, pga);
|
||||
addFormSelector(F("Gain"), F("plugin_025_gain"), ADS1115_PGA_OPTION, pgaOptions, NULL, pga);
|
||||
|
||||
#define ADS1115_MUX_OPTION 8
|
||||
byte mux = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
|
||||
@@ -95,19 +95,19 @@ boolean Plugin_025(byte function, struct EventStruct *event, String& string)
|
||||
F("AIN2 - GND (Single-Ended)"),
|
||||
F("AIN3 - GND (Single-Ended)"),
|
||||
};
|
||||
addFormSelector(string, F("Input Multiplexer"), F("plugin_025_mode"), ADS1115_MUX_OPTION, muxOptions, NULL, mux);
|
||||
addFormSelector(F("Input Multiplexer"), F("plugin_025_mode"), ADS1115_MUX_OPTION, muxOptions, NULL, mux);
|
||||
|
||||
addFormSubHeader(string, F("Two Point Calibration"));
|
||||
addFormSubHeader(F("Two Point Calibration"));
|
||||
|
||||
addFormCheckBox(string, F("Calibration Enabled"), F("plugin_025_cal"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
addFormCheckBox(F("Calibration Enabled"), F("plugin_025_cal"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
|
||||
addFormNumericBox(string, F("Point 1"), F("plugin_025_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], -32768, 32767);
|
||||
string += F(" ≙ ");
|
||||
addTextBox(string, F("plugin_025_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
|
||||
addFormNumericBox(F("Point 1"), F("plugin_025_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], -32768, 32767);
|
||||
addHtml(F(" ≙ "));
|
||||
addTextBox(F("plugin_025_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
|
||||
|
||||
addFormNumericBox(string, F("Point 2"), F("plugin_025_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], -32768, 32767);
|
||||
string += F(" ≙ ");
|
||||
addTextBox(string, F("plugin_025_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
|
||||
addFormNumericBox(F("Point 2"), F("plugin_025_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], -32768, 32767);
|
||||
addHtml(F(" ≙ "));
|
||||
addTextBox(F("plugin_025_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -52,7 +52,7 @@ boolean Plugin_026(byte function, struct EventStruct *event, String& string)
|
||||
options[7] = F("IP 3.Octet");
|
||||
options[8] = F("IP 4.Octet");
|
||||
options[9] = F("Web activity");
|
||||
addFormSelector(string, F("Indicator"), F("plugin_026"), 10, options, NULL, choice);
|
||||
addFormSelector(F("Indicator"), F("plugin_026"), 10, options, NULL, choice);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -138,13 +138,13 @@ boolean Plugin_027(byte function, struct EventStruct *event, String& string)
|
||||
optionValuesMode[0] = 0;
|
||||
optionValuesMode[1] = 1;
|
||||
optionValuesMode[2] = 2;
|
||||
addFormSelector(string, F("Measure range"), F("plugin_027_range"), 3, optionsMode, optionValuesMode, choiceMode);
|
||||
addFormSelector(F("Measure range"), F("plugin_027_range"), 3, optionsMode, optionValuesMode, choiceMode);
|
||||
|
||||
addFormSelectorI2C(string, F("plugin_027_i2c"), 4, Plugin_27_i2c_addresses, Plugin_027_i2c_addr(event));
|
||||
addFormSelectorI2C(F("plugin_027_i2c"), 4, Plugin_27_i2c_addresses, Plugin_027_i2c_addr(event));
|
||||
|
||||
byte choiceMeasureType = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
|
||||
String options[4] = { F("Voltage"), F("Current"), F("Power"), F("Voltage/Current/Power") };
|
||||
addFormSelector(string, F("Measurement Type"), F("plugin_027_measuretype"), 4, options, NULL, choiceMeasureType );
|
||||
addFormSelector(F("Measurement Type"), F("plugin_027_measuretype"), 4, options, NULL, choiceMeasureType );
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -213,25 +213,25 @@ boolean Plugin_028(byte function, struct EventStruct *event, String& string)
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
const uint8_t i2cAddress = Plugin_028_i2c_addr(event);
|
||||
addFormSelectorI2C(string, F("plugin_028_bme280_i2c"), 2, Plugin_28_i2c_addresses, i2cAddress);
|
||||
addFormSelectorI2C(F("plugin_028_bme280_i2c"), 2, Plugin_28_i2c_addresses, i2cAddress);
|
||||
const uint8_t idx = Plugin_028_device_index(i2cAddress);
|
||||
if (_sensorID[idx] != Unknown_DEVICE) {
|
||||
String detectedString = F("Detected: ");
|
||||
detectedString += Plugin_028_getFullDeviceName();
|
||||
addUnit(string, detectedString);
|
||||
addUnit(detectedString);
|
||||
}
|
||||
addFormNote(string, F("SDO Low=0x76, High=0x77"));
|
||||
addFormNote(F("SDO Low=0x76, High=0x77"));
|
||||
|
||||
addFormNumericBox(string, F("Altitude"), F("plugin_028_bme280_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addUnit(string, F("m"));
|
||||
addFormNumericBox(F("Altitude"), F("plugin_028_bme280_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addUnit(F("m"));
|
||||
|
||||
addFormNumericBox(string, F("Temperature offset"), F("plugin_028_bme280_tempoffset"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
addUnit(string, F("x 0.1C"));
|
||||
addFormNumericBox(F("Temperature offset"), F("plugin_028_bme280_tempoffset"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
addUnit(F("x 0.1C"));
|
||||
String offsetNote = F("Offset in units of 0.1 degree Celcius");
|
||||
if (Plugin_028_hasHumidity()) {
|
||||
offsetNote += F(" (also correct humidity)");
|
||||
}
|
||||
addFormNote(string, offsetNote);
|
||||
addFormNote(offsetNote);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -50,10 +50,10 @@ boolean Plugin_029(byte function, struct EventStruct *event, String& string)
|
||||
if (Settings.Protocol[i] == 2) { controllerNr = i; }
|
||||
}
|
||||
|
||||
string += F("<TR><TD>IDX:<TD>");
|
||||
addHtml(F("<TR><TD>IDX:<TD>"));
|
||||
String id = F("TDID"); //="taskdeviceid"
|
||||
id += controllerNr + 1;
|
||||
addNumericBox(string, id, Settings.TaskDeviceID[controllerNr][event->TaskIndex], 0, 9999);
|
||||
addNumericBox(id, Settings.TaskDeviceID[controllerNr][event->TaskIndex], 0, 9999);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -106,11 +106,11 @@ boolean Plugin_030(byte function, struct EventStruct *event, String& string)
|
||||
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
|
||||
/*String options[2] = { F("0x76 - default settings (SDO Low)"), F("0x77 - alternate settings (SDO HIGH)") };*/
|
||||
int optionValues[2] = { 0x76, 0x77 };
|
||||
addFormSelectorI2C(string, F("plugin_030_bmp280_i2c"), 2, optionValues, choice);
|
||||
addFormNote(string, F("SDO Low=0x76, High=0x77"));
|
||||
addFormSelectorI2C(F("plugin_030_bmp280_i2c"), 2, optionValues, choice);
|
||||
addFormNote(F("SDO Low=0x76, High=0x77"));
|
||||
|
||||
addFormNumericBox(string, F("Altitude"), F("plugin_030_bmp280_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addUnit(string, F("m"));
|
||||
addFormNumericBox(F("Altitude"), F("plugin_030_bmp280_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addUnit(F("m"));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -73,9 +73,9 @@ boolean Plugin_032(byte function, struct EventStruct *event, String& string)
|
||||
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
|
||||
/*String options[2] = { F("0x77 - default I2C address"), F("0x76 - alternate I2C address") };*/
|
||||
int optionValues[2] = { 0x77, 0x76 };
|
||||
addFormSelectorI2C(string, F("plugin_032_ms5611_i2c"), 2, optionValues, choice);
|
||||
addFormSelectorI2C(F("plugin_032_ms5611_i2c"), 2, optionValues, choice);
|
||||
|
||||
addFormNumericBox(string, F("Altitude [m]"), F("plugin_032_ms5611_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addFormNumericBox(F("Altitude [m]"), F("plugin_032_ms5611_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ boolean Plugin_033(byte function, struct EventStruct *event, String& string)
|
||||
optionValues[9] = SENSOR_TYPE_LONG;
|
||||
optionValues[10] = SENSOR_TYPE_WIND;
|
||||
|
||||
addFormSelector(string, F("Simulate Data Type"), F("plugin_033_sensortype"), 11, options, optionValues, choice );
|
||||
addFormSelector(F("Simulate Data Type"), F("plugin_033_sensortype"), 11, options, optionValues, choice );
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+13
-13
@@ -26,10 +26,10 @@
|
||||
#define P36_CONTRAST_HIGH 0xFF
|
||||
|
||||
|
||||
#include "SSD1306.h"
|
||||
#include "SH1106Wire.h"
|
||||
#include "OLED_SSD1306_SH1106_images.h"
|
||||
#include "Dialog_Plain_12_font.h"
|
||||
#include "SSD1306.h"
|
||||
#include "SH1106Wire.h"
|
||||
#include "OLED_SSD1306_SH1106_images.h"
|
||||
#include "Dialog_Plain_12_font.h"
|
||||
|
||||
#define P36_WIFI_STATE_UNSET -2
|
||||
#define P36_WIFI_STATE_NOT_CONNECTED -1
|
||||
@@ -94,7 +94,7 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
|
||||
options5[0] = F("SSD1306");
|
||||
options5[1] = F("SH1106");
|
||||
int optionValues5[2] = { 1, 2 };
|
||||
addFormSelector(string, F("Controler"), F("plugin_036_controler"), 2, options5, optionValues5, choice5);
|
||||
addFormSelector(F("Controler"), F("plugin_036_controler"), 2, options5, optionValues5, choice5);
|
||||
|
||||
byte choice0 = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
|
||||
/*
|
||||
@@ -105,14 +105,14 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
|
||||
int optionValues0[2];
|
||||
optionValues0[0] = 0x3C;
|
||||
optionValues0[1] = 0x3D;
|
||||
addFormSelectorI2C(string, F("plugin_036_adr"), 2, optionValues0, choice0);
|
||||
addFormSelectorI2C(F("plugin_036_adr"), 2, optionValues0, choice0);
|
||||
|
||||
byte choice1 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
|
||||
String options1[2];
|
||||
options1[0] = F("Normal");
|
||||
options1[1] = F("Rotated");
|
||||
int optionValues1[2] = { 1, 2 };
|
||||
addFormSelector(string, F("Rotation"), F("plugin_036_rotate"), 2, options1, optionValues1, choice1);
|
||||
addFormSelector(F("Rotation"), F("plugin_036_rotate"), 2, options1, optionValues1, choice1);
|
||||
|
||||
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
|
||||
String options2[4];
|
||||
@@ -121,7 +121,7 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
|
||||
options2[2] = F("3");
|
||||
options2[3] = F("4");
|
||||
int optionValues2[4] = { 1, 2, 3, 4 };
|
||||
addFormSelector(string, F("Lines per Frame"), F("plugin_036_nlines"), 4, options2, optionValues2, choice2);
|
||||
addFormSelector(F("Lines per Frame"), F("plugin_036_nlines"), 4, options2, optionValues2, choice2);
|
||||
|
||||
byte choice3 = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
|
||||
String options3[5];
|
||||
@@ -136,18 +136,18 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
|
||||
optionValues3[2] = 4;
|
||||
optionValues3[3] = 8;
|
||||
optionValues3[4] = 32;
|
||||
addFormSelector(string, F("Scroll"), F("plugin_036_scroll"), 5, options3, optionValues3, choice3);
|
||||
addFormSelector(F("Scroll"), F("plugin_036_scroll"), 5, options3, optionValues3, choice3);
|
||||
|
||||
LoadCustomTaskSettings(event->TaskIndex, (byte*)&P036_deviceTemplate, sizeof(P036_deviceTemplate));
|
||||
|
||||
for (byte varNr = 0; varNr < P36_Nlines; varNr++)
|
||||
{
|
||||
addFormTextBox(string, String(F("Line ")) + (varNr + 1), String(F("Plugin_036_template")) + (varNr + 1), P036_deviceTemplate[varNr], P36_Nchars);
|
||||
addFormTextBox(String(F("Line ")) + (varNr + 1), String(F("Plugin_036_template")) + (varNr + 1), P036_deviceTemplate[varNr], P36_Nchars);
|
||||
}
|
||||
|
||||
addFormPinSelect(string, F("Display button"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
|
||||
addFormPinSelect(F("Display button"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
|
||||
|
||||
addFormNumericBox(string, F("Display Timeout"), F("plugin_036_timer"), Settings.TaskDevicePluginConfig[event->TaskIndex][4]);
|
||||
addFormNumericBox(F("Display Timeout"), F("plugin_036_timer"), Settings.TaskDevicePluginConfig[event->TaskIndex][4]);
|
||||
|
||||
byte choice6 = Settings.TaskDevicePluginConfig[event->TaskIndex][6];
|
||||
if (choice6 == 0) choice6 = P36_CONTRAST_HIGH;
|
||||
@@ -159,7 +159,7 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
|
||||
optionValues6[0] = P36_CONTRAST_LOW;
|
||||
optionValues6[1] = P36_CONTRAST_MED;
|
||||
optionValues6[2] = P36_CONTRAST_HIGH;
|
||||
addFormSelector(string, F("Contrast"), F("plugin_036_contrast"), 3, options6, optionValues6, choice6);
|
||||
addFormSelector(F("Contrast"), F("plugin_036_contrast"), 3, options6, optionValues6, choice6);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -92,7 +92,7 @@ boolean Plugin_037(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
for (byte varNr = 0; varNr < 4; varNr++)
|
||||
{
|
||||
addFormTextBox(string, String(F("MQTT Topic ")) + (varNr + 1), String(F("Plugin_037_template")) +
|
||||
addFormTextBox(String(F("MQTT Topic ")) + (varNr + 1), String(F("Plugin_037_template")) +
|
||||
(varNr + 1), deviceTemplate[varNr], 40);
|
||||
}
|
||||
success = true;
|
||||
|
||||
@@ -65,9 +65,9 @@ boolean Plugin_038(byte function, struct EventStruct *event, String& string)
|
||||
const String options[] = { F("GRB"), F("GRBW") };
|
||||
int indices[] = { 1, 2 };
|
||||
|
||||
addFormNumericBox(string, F("Led Count"), F("plugin_038_leds"), Settings.TaskDevicePluginConfig[event->TaskIndex][0],1,999);
|
||||
addFormPinSelect(string, F("GPIO"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]);
|
||||
addFormSelector(string, F("Strip Type"), F("plugin_038_strip"), 2, options, indices, Settings.TaskDevicePluginConfig[event->TaskIndex][1] );
|
||||
addFormNumericBox(F("Led Count"), F("plugin_038_leds"), Settings.TaskDevicePluginConfig[event->TaskIndex][0],1,999);
|
||||
addFormPinSelect(F("GPIO"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]);
|
||||
addFormSelector(F("Strip Type"), F("plugin_038_strip"), 2, options, indices, Settings.TaskDevicePluginConfig[event->TaskIndex][1] );
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -104,8 +104,8 @@ boolean Plugin_039(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormNote(string, F("<b>1st GPIO</b> = CS (Usable GPIOs : 0, 2, 4, 5, 15)"));
|
||||
//string += F("<TR><TD>Info GPIO:<TD><b>1st GPIO</b> = CS (Usable GPIOs : 0, 2, 4, 5, 15)");
|
||||
addFormNote(F("<b>1st GPIO</b> = CS (Usable GPIOs : 0, 2, 4, 5, 15)"));
|
||||
//addHtml(F("<TR><TD>Info GPIO:<TD><b>1st GPIO</b> = CS (Usable GPIOs : 0, 2, 4, 5, 15)"));
|
||||
|
||||
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
|
||||
String options[2];
|
||||
@@ -113,7 +113,7 @@ boolean Plugin_039(byte function, struct EventStruct *event, String& string)
|
||||
options[1] = F("MAX 31855");
|
||||
//options[2] = F("MAX 31865");
|
||||
int optionValues[2] = { 1, 2 };
|
||||
addFormSelector(string, F("Adapter IC"), F("plugin_039_maxtype"), 2, options, optionValues, choice);
|
||||
addFormSelector(F("Adapter IC"), F("plugin_039_maxtype"), 2, options, optionValues, choice);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -51,9 +51,9 @@ boolean Plugin_041(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormNumericBox(string, F("Red"), F("plugin_041_red"), Settings.TaskDevicePluginConfig[event->TaskIndex][0], 0, 255);
|
||||
addFormNumericBox(string, F("Green"), F("plugin_041_green"), Settings.TaskDevicePluginConfig[event->TaskIndex][1], 0, 255);
|
||||
addFormNumericBox(string, F("Blue"), F("plugin_041_blue"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 255);
|
||||
addFormNumericBox(F("Red"), F("plugin_041_red"), Settings.TaskDevicePluginConfig[event->TaskIndex][0], 0, 255);
|
||||
addFormNumericBox(F("Green"), F("plugin_041_green"), Settings.TaskDevicePluginConfig[event->TaskIndex][1], 0, 255);
|
||||
addFormNumericBox(F("Blue"), F("plugin_041_blue"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 255);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
+34
-34
@@ -135,7 +135,7 @@ boolean Plugin_042(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
string += F("<script src=\"jscolor.min.js\"></script>\n");
|
||||
addHtml(F("<script src=\"jscolor.min.js\"></script>\n"));
|
||||
|
||||
char tmpString[128];
|
||||
String options[8];
|
||||
@@ -157,25 +157,25 @@ boolean Plugin_042(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
|
||||
// Candle Type Selection
|
||||
addFormSelector(string, F("Flame Type"), F("web_Candle_Type"), 8, options, NULL, choice);
|
||||
addFormSelector(F("Flame Type"), F("web_Candle_Type"), 8, options, NULL, choice);
|
||||
|
||||
// Advanced Color options
|
||||
Candle_color = (ColorType)Settings.TaskDevicePluginConfig[event->TaskIndex][5];
|
||||
string += F("<TR><TD>Color Handling:<TD>"); // checked
|
||||
string += F("<input type='radio' id='web_Color_Default' name='web_Color_Type' value='0'");
|
||||
addHtml(F("<TR><TD>Color Handling:<TD>")); // checked
|
||||
addHtml(F("<input type='radio' id='web_Color_Default' name='web_Color_Type' value='0'"));
|
||||
if (Candle_color == ColorDefault) {
|
||||
string += F(" checked>");
|
||||
addHtml(F(" checked>"));
|
||||
} else {
|
||||
string += F(">");
|
||||
addHtml(F(">"));
|
||||
}
|
||||
string += F("<label for='web_Color_Default'> Use default color</label><br>");
|
||||
string += F("<input type='radio' id='web_Color_Selected' name='web_Color_Type' value='1'");
|
||||
addHtml(F("<label for='web_Color_Default'> Use default color</label><br>"));
|
||||
addHtml(F("<input type='radio' id='web_Color_Selected' name='web_Color_Type' value='1'"));
|
||||
if (Candle_color == ColorSelected) {
|
||||
string += F(" checked>");
|
||||
addHtml(F(" checked>"));
|
||||
} else {
|
||||
string += F(">");
|
||||
addHtml(F(">"));
|
||||
}
|
||||
string += F("<label for='web_Color_Selected'> Use selected color</label><br>");
|
||||
addHtml(F("<label for='web_Color_Selected'> Use selected color</label><br>"));
|
||||
|
||||
// Color Selection
|
||||
char hexvalue[7] = {0};
|
||||
@@ -185,36 +185,36 @@ boolean Plugin_042(byte function, struct EventStruct *event, String& string)
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
|
||||
// http://jscolor.com/examples/
|
||||
string += F("<TR><TD>Color:<TD><input class=\"jscolor {onFineChange:'update(this)'}\" value='");
|
||||
string += hexvalue;
|
||||
string += F("'>");
|
||||
addFormNumericBox(string, F("RGB Color"), F("web_RGB_Red"), Settings.TaskDevicePluginConfig[event->TaskIndex][0], 0, 255);
|
||||
addNumericBox(string, F("web_RGB_Green"), Settings.TaskDevicePluginConfig[event->TaskIndex][1], 0, 255);
|
||||
addNumericBox(string, F("web_RGB_Blue"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 255);
|
||||
addHtml(F("<TR><TD>Color:<TD><input class=\"jscolor {onFineChange:'update(this)'}\" value='"));
|
||||
addHtml(hexvalue);
|
||||
addHtml(F("'>"));
|
||||
addFormNumericBox(F("RGB Color"), F("web_RGB_Red"), Settings.TaskDevicePluginConfig[event->TaskIndex][0], 0, 255);
|
||||
addNumericBox(F("web_RGB_Green"), Settings.TaskDevicePluginConfig[event->TaskIndex][1], 0, 255);
|
||||
addNumericBox(F("web_RGB_Blue"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 255);
|
||||
|
||||
// Brightness Selection
|
||||
string += F("<TR><TD>Brightness:<TD>min<input type='range' id='web_Bright_Slide' min='0' max='255' value='");
|
||||
string += Settings.TaskDevicePluginConfig[event->TaskIndex][3];
|
||||
string += F("'> max");
|
||||
addHtml(F("<TR><TD>Brightness:<TD>min<input type='range' id='web_Bright_Slide' min='0' max='255' value='"));
|
||||
addHtml(String(Settings.TaskDevicePluginConfig[event->TaskIndex][3]));
|
||||
addHtml(F("'> max"));
|
||||
|
||||
sprintf_P(tmpString, PSTR("<TR><TD>Brightness Value:<TD><input type='text' name='web_Bright_Text' id='web_Bright_Text' size='3' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
string += tmpString;
|
||||
addHtml(tmpString);
|
||||
|
||||
// Some Javascript we need to update the items
|
||||
string += F("<script script type='text/javascript'>");
|
||||
string += F("function update(picker) {");
|
||||
string += F(" document.getElementById('web_RGB_Red').value = Math.round(picker.rgb[0]);");
|
||||
string += F(" document.getElementById('web_RGB_Green').value = Math.round(picker.rgb[1]);");
|
||||
string += F(" document.getElementById('web_RGB_Blue').value = Math.round(picker.rgb[2]);");
|
||||
string += F("}");
|
||||
string += F("</script>");
|
||||
addHtml(F("<script script type='text/javascript'>"));
|
||||
addHtml(F("function update(picker) {"));
|
||||
addHtml(F(" document.getElementById('web_RGB_Red').value = Math.round(picker.rgb[0]);"));
|
||||
addHtml(F(" document.getElementById('web_RGB_Green').value = Math.round(picker.rgb[1]);"));
|
||||
addHtml(F(" document.getElementById('web_RGB_Blue').value = Math.round(picker.rgb[2]);"));
|
||||
addHtml(F("}"));
|
||||
addHtml(F("</script>"));
|
||||
|
||||
string += F("<script type='text/javascript'>window.addEventListener('load', function(){");
|
||||
string += F("var slider = document.getElementById('web_Bright_Slide');");
|
||||
string += F("slider.addEventListener('change', function(){");
|
||||
string += F("document.getElementById('web_Bright_Text').value = this.value;");
|
||||
string += F("});");
|
||||
string += F("});</script>");
|
||||
addHtml(F("<script type='text/javascript'>window.addEventListener('load', function(){"));
|
||||
addHtml(F("var slider = document.getElementById('web_Bright_Slide');"));
|
||||
addHtml(F("slider.addEventListener('change', function(){"));
|
||||
addHtml(F("document.getElementById('web_Bright_Text').value = this.value;"));
|
||||
addHtml(F("});"));
|
||||
addHtml(F("});</script>"));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+10
-10
@@ -50,18 +50,18 @@ boolean Plugin_043(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
for (byte x = 0; x < PLUGIN_043_MAX_SETTINGS; x++)
|
||||
{
|
||||
addFormTextBox(string, String(F("Day,Time ")) + (x + 1), String(F("plugin_043_clock")) + (x), timeLong2String(ExtraTaskSettings.TaskDevicePluginConfigLong[x]), 32);
|
||||
// string += F("<TR><TD>Day,Time ");
|
||||
// string += x+1;
|
||||
// string += F(":<TD><input type='text' name='plugin_043_clock");
|
||||
// string += x;
|
||||
// string += F("' value='");
|
||||
// string += timeLong2String(ExtraTaskSettings.TaskDevicePluginConfigLong[x]);
|
||||
// string += F("'>");
|
||||
addFormTextBox(String(F("Day,Time ")) + (x + 1), String(F("plugin_043_clock")) + (x), timeLong2String(ExtraTaskSettings.TaskDevicePluginConfigLong[x]), 32);
|
||||
// addHtml(F("<TR><TD>Day,Time "));
|
||||
// addHtml(x+1);
|
||||
// addHtml(F(":<TD><input type='text' name='plugin_043_clock"));
|
||||
// addHtml(x);
|
||||
// addHtml(F("' value='"));
|
||||
// addHtml(timeLong2String(ExtraTaskSettings.TaskDevicePluginConfigLong[x]));
|
||||
// addHtml(F("'>"));
|
||||
|
||||
string += F(" ");
|
||||
addHtml(F(" "));
|
||||
byte choice = ExtraTaskSettings.TaskDevicePluginConfig[x];
|
||||
addSelector(string, String(F("plugin_043_state")) + (x), 3, options, NULL, NULL, choice, false);
|
||||
addSelector(String(F("plugin_043_state")) + (x), 3, options, NULL, NULL, choice, false);
|
||||
}
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -66,9 +66,9 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormNumericBox(string, F("TCP Port"), F("plugin_044_port"), ExtraTaskSettings.TaskDevicePluginConfigLong[0]);
|
||||
addFormNumericBox(string, F("Baud Rate"), F("plugin_044_baud"), ExtraTaskSettings.TaskDevicePluginConfigLong[1]);
|
||||
addFormNumericBox(string, F("Data bits"), F("plugin_044_data"), ExtraTaskSettings.TaskDevicePluginConfigLong[2]);
|
||||
addFormNumericBox(F("TCP Port"), F("plugin_044_port"), ExtraTaskSettings.TaskDevicePluginConfigLong[0]);
|
||||
addFormNumericBox(F("Baud Rate"), F("plugin_044_baud"), ExtraTaskSettings.TaskDevicePluginConfigLong[1]);
|
||||
addFormNumericBox(F("Data bits"), F("plugin_044_data"), ExtraTaskSettings.TaskDevicePluginConfigLong[2]);
|
||||
|
||||
byte choice = ExtraTaskSettings.TaskDevicePluginConfigLong[3];
|
||||
String options[3];
|
||||
@@ -76,13 +76,13 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string)
|
||||
options[1] = F("Even");
|
||||
options[2] = F("Odd");
|
||||
int optionValues[3] = { 0, 2, 3 };
|
||||
addFormSelector(string, F("Parity"), F("plugin_044_parity"), 3, options, optionValues, choice);
|
||||
addFormSelector(F("Parity"), F("plugin_044_parity"), 3, options, optionValues, choice);
|
||||
|
||||
addFormNumericBox(string, F("Stop bits"), F("plugin_044_stop"), ExtraTaskSettings.TaskDevicePluginConfigLong[4]);
|
||||
addFormNumericBox(F("Stop bits"), F("plugin_044_stop"), ExtraTaskSettings.TaskDevicePluginConfigLong[4]);
|
||||
|
||||
addFormPinSelect(string, F("Reset target after boot"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]);
|
||||
addFormPinSelect(F("Reset target after boot"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]);
|
||||
|
||||
addFormNumericBox(string, F("RX Receive Timeout (mSec)"), F("plugin_044_rxwait"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
addFormNumericBox(F("RX Receive Timeout (mSec)"), F("plugin_044_rxwait"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+17
-17
@@ -123,8 +123,8 @@ boolean Plugin_045(byte function, struct EventStruct *event, String& string)
|
||||
int optionValues[2];
|
||||
optionValues[0] = 0x68;
|
||||
optionValues[1] = 0x69;
|
||||
addFormSelectorI2C(string, F("plugin_045_address"), 2, optionValues, choice);
|
||||
addFormNote(string, F("ADDR Low=0x68, High=0x69"));
|
||||
addFormSelectorI2C(F("plugin_045_address"), 2, optionValues, choice);
|
||||
addFormNote(F("ADDR Low=0x68, High=0x69"));
|
||||
|
||||
choice = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
|
||||
String options[10];
|
||||
@@ -138,28 +138,28 @@ boolean Plugin_045(byte function, struct EventStruct *event, String& string)
|
||||
options[7] = F("G-force X");
|
||||
options[8] = F("G-force Y");
|
||||
options[9] = F("G-force Z");
|
||||
addFormSelector(string, F("Function"), F("plugin_045_function"), 10, options, NULL, choice);
|
||||
addFormSelector(F("Function"), F("plugin_045_function"), 10, options, NULL, choice);
|
||||
|
||||
if (choice == 0) {
|
||||
// If this is instance function 0, setup webform for additional vars
|
||||
// Show some user information about the webform and what the vars mean.
|
||||
string += F("<TR><TD><TD>The thresholdvalues (0-65535) can be used to set a threshold for one or more<br>");
|
||||
string += F("axis. The axis will trigger when the range for that axis exceeds the threshold<br>");
|
||||
string += F("value. A value of 0 disables movement detection for that axis.");
|
||||
addHtml(F("<TR><TD><TD>The thresholdvalues (0-65535) can be used to set a threshold for one or more<br>"));
|
||||
addHtml(F("axis. The axis will trigger when the range for that axis exceeds the threshold<br>"));
|
||||
addHtml(F("value. A value of 0 disables movement detection for that axis."));
|
||||
|
||||
addFormNumericBox(string, F("Detection threshold X"), F("plugin_045_threshold_x"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 65535);
|
||||
addFormNumericBox(string, F("Detection threshold Y"), F("plugin_045_threshold_y"), Settings.TaskDevicePluginConfig[event->TaskIndex][3], 0, 65535);
|
||||
addFormNumericBox(string, F("Detection threshold Z"), F("plugin_045_threshold_z"), Settings.TaskDevicePluginConfig[event->TaskIndex][4], 0, 65535);
|
||||
addFormNumericBox(F("Detection threshold X"), F("plugin_045_threshold_x"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 65535);
|
||||
addFormNumericBox(F("Detection threshold Y"), F("plugin_045_threshold_y"), Settings.TaskDevicePluginConfig[event->TaskIndex][3], 0, 65535);
|
||||
addFormNumericBox(F("Detection threshold Z"), F("plugin_045_threshold_z"), Settings.TaskDevicePluginConfig[event->TaskIndex][4], 0, 65535);
|
||||
|
||||
string += F("<TR><TD><TD>Each 30 seconds a counter for the detection window is increased plus all axis<br>");
|
||||
string += F("are checked and if they *all* exceeded the threshold values, a counter is increased.<br>");
|
||||
string += F("Each period, defined by the [detection window], the counter is checked against<br>");
|
||||
string += F("the [min. detection count] and if found equal or larger, movement is detected.<br>");
|
||||
string += F("If in the next window the [min. detection count] value is not met, movement has stopped.");
|
||||
string += F("The [detection window] cannot be smaller than the [min. detection count].");
|
||||
addHtml(F("<TR><TD><TD>Each 30 seconds a counter for the detection window is increased plus all axis<br>"));
|
||||
addHtml(F("are checked and if they *all* exceeded the threshold values, a counter is increased.<br>"));
|
||||
addHtml(F("Each period, defined by the [detection window], the counter is checked against<br>"));
|
||||
addHtml(F("the [min. detection count] and if found equal or larger, movement is detected.<br>"));
|
||||
addHtml(F("If in the next window the [min. detection count] value is not met, movement has stopped."));
|
||||
addHtml(F("The [detection window] cannot be smaller than the [min. detection count]."));
|
||||
|
||||
addFormNumericBox(string, F("Min. detection count"), F("plugin_045_threshold_counter"), Settings.TaskDevicePluginConfig[event->TaskIndex][5], 0, 999999);
|
||||
addFormNumericBox(string, F("Detection window"), F("plugin_045_threshold_window"), Settings.TaskDevicePluginConfig[event->TaskIndex][6], 0, 999999);
|
||||
addFormNumericBox(F("Min. detection count"), F("plugin_045_threshold_counter"), Settings.TaskDevicePluginConfig[event->TaskIndex][5], 0, 999999);
|
||||
addFormNumericBox(F("Detection window"), F("plugin_045_threshold_window"), Settings.TaskDevicePluginConfig[event->TaskIndex][6], 0, 999999);
|
||||
|
||||
}
|
||||
success = true;
|
||||
|
||||
+28
-28
@@ -155,74 +155,74 @@ boolean Plugin_046(byte function, struct EventStruct *event, String& string)
|
||||
options[7] = F("Unknown 2, byte 16");
|
||||
options[8] = F("Unknown 3, byte 19");
|
||||
|
||||
addFormSelector(string, F("Plugin function"), F("plugin_046"), nrchoices, options, NULL, choice);
|
||||
addFormSelector(F("Plugin function"), F("plugin_046"), nrchoices, options, NULL, choice);
|
||||
|
||||
if (choice==0) {
|
||||
string += F("<TR><TD>1st GPIO (5-MOSI):<TD>");
|
||||
addPinSelect(false, string, "taskdevicepin1", Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
string += F("<TR><TD>2nd GPIO (6-SCLK):<TD>");
|
||||
addPinSelect(false, string, "taskdevicepin2", Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
string += F("<TR><TD>3rd GPIO (7-nSEL):<TD>");
|
||||
addPinSelect(false, string, "taskdevicepin3", Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
string += F("<TR><TD>4th GPIO (8-MISO):<TD>");
|
||||
addPinSelect(false, string, "taskdeviceport", Settings.TaskDevicePluginConfig[event->TaskIndex][4]);
|
||||
addHtml(F("<TR><TD>1st GPIO (5-MOSI):<TD>"));
|
||||
addPinSelect(false, "taskdevicepin1", Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addHtml(F("<TR><TD>2nd GPIO (6-SCLK):<TD>"));
|
||||
addPinSelect(false, "taskdevicepin2", Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
addHtml(F("<TR><TD>3rd GPIO (7-nSEL):<TD>"));
|
||||
addPinSelect(false, "taskdevicepin3", Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
addHtml(F("<TR><TD>4th GPIO (8-MISO):<TD>"));
|
||||
addPinSelect(false, "taskdeviceport", Settings.TaskDevicePluginConfig[event->TaskIndex][4]);
|
||||
}
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
case (0):
|
||||
{
|
||||
string += F("<TR><TD><B>Be sure you only have 1 main plugin!</B></TD>");
|
||||
string += F("<TR><TD>Value 1: Temperature, 1 decimal<BR>Value 2: Humidity, 0 decimals");
|
||||
string += F("<BR>Value 3: not used</TD>");
|
||||
addHtml(F("<TR><TD><B>Be sure you only have 1 main plugin!</B></TD>"));
|
||||
addHtml(F("<TR><TD>Value 1: Temperature, 1 decimal<BR>Value 2: Humidity, 0 decimals"));
|
||||
addHtml(F("<BR>Value 3: not used</TD>"));
|
||||
break;
|
||||
}
|
||||
case (1):
|
||||
{
|
||||
string += F("<TR><TD>Value 1: Direction, 0 decimals<BR>");
|
||||
string += F("Value 2: Average, 1 decimal<Br>Value 3: Gust, 1 decimal</TD>");
|
||||
addHtml(F("<TR><TD>Value 1: Direction, 0 decimals<BR>"));
|
||||
addHtml(F("Value 2: Average, 1 decimal<Br>Value 3: Gust, 1 decimal</TD>"));
|
||||
break;
|
||||
}
|
||||
case (2):
|
||||
{
|
||||
string += F("<TR><TD>Value 1: Rain in mm per hour<BR>Value 2: Total rain in mm");
|
||||
string += F("<BR>Value 3: not used</TD>");
|
||||
addHtml(F("<TR><TD>Value 1: Rain in mm per hour<BR>Value 2: Total rain in mm"));
|
||||
addHtml(F("<BR>Value 3: not used</TD>"));
|
||||
break;
|
||||
}
|
||||
case (3):
|
||||
{
|
||||
string += F("<TR><TD>Value 1: UV, 1 decimal");
|
||||
string += F("<BR>Values 2, 3</TD>");
|
||||
addHtml(F("<TR><TD>Value 1: UV, 1 decimal"));
|
||||
addHtml(F("<BR>Values 2, 3</TD>"));
|
||||
break;
|
||||
}
|
||||
case (4):
|
||||
{
|
||||
string += F("<TR><TD>Value 1: Strikes this hour, 0 decimals");
|
||||
string += F("<BR>Values 2, 3: not used</TD>");
|
||||
addHtml(F("<TR><TD>Value 1: Strikes this hour, 0 decimals"));
|
||||
addHtml(F("<BR>Values 2, 3: not used</TD>"));
|
||||
break;
|
||||
}
|
||||
case (5):
|
||||
{
|
||||
string += F("<TR><TD>Value 1: Distance in km, 0 decimals");
|
||||
string += F("<BR>Values 2, 3: not used</TD>");
|
||||
addHtml(F("<TR><TD>Value 1: Distance in km, 0 decimals"));
|
||||
addHtml(F("<BR>Values 2, 3: not used</TD>"));
|
||||
break;
|
||||
}
|
||||
case (6):
|
||||
{
|
||||
string += F("<TR><TD>Value 1: Batterybyte, 0 decimals");
|
||||
string += F("<BR>Values 2, 3: not used</TD>");
|
||||
addHtml(F("<TR><TD>Value 1: Batterybyte, 0 decimals"));
|
||||
addHtml(F("<BR>Values 2, 3: not used</TD>"));
|
||||
break;
|
||||
}
|
||||
case (7):
|
||||
{
|
||||
string += F("<TR><TD>Value 1: Last rainbyte, 0 decimals");
|
||||
string += F("<BR>Values 2, 3: not used</TD>");
|
||||
addHtml(F("<TR><TD>Value 1: Last rainbyte, 0 decimals"));
|
||||
addHtml(F("<BR>Values 2, 3: not used</TD>"));
|
||||
break;
|
||||
}
|
||||
case (8):
|
||||
{
|
||||
string += F("<TR><TD>Value 1: Last lightningbyte, 0 decimals");
|
||||
string += F("<BR>Values 2, 3: not used</TD>");
|
||||
addHtml(F("<TR><TD>Value 1: Last lightningbyte, 0 decimals"));
|
||||
addHtml(F("<BR>Values 2, 3: not used</TD>"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,20 +76,20 @@ boolean Plugin_047(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormTextBox(string, F("I2C Address (Hex)"), F("plugin_047_i2cSoilMoisture_i2cAddress"), String(F("0x")) +
|
||||
addFormTextBox(F("I2C Address (Hex)"), F("plugin_047_i2cSoilMoisture_i2cAddress"), String(F("0x")) +
|
||||
String(Settings.TaskDevicePluginConfig[event->TaskIndex][0],HEX), 4);
|
||||
|
||||
addFormCheckBox(string, F("Send sensor to sleep"), F("plugin_047_sleep"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addFormCheckBox(F("Send sensor to sleep"), F("plugin_047_sleep"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
|
||||
addFormCheckBox(string, F("Check sensor version") ,F("plugin_047_version"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
addFormCheckBox(F("Check sensor version") ,F("plugin_047_version"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
|
||||
addFormSeparator(string);
|
||||
addFormSeparator(2);
|
||||
|
||||
addFormCheckBox(string, F("Change Sensor address"),F("plugin_047_changeAddr"), false);
|
||||
addFormTextBox(string, F("Change I2C Addr. to (Hex)"), F("plugin_047_i2cSoilMoisture_changeAddr"), String(F("0x")) +
|
||||
addFormCheckBox(F("Change Sensor address"),F("plugin_047_changeAddr"), false);
|
||||
addFormTextBox(F("Change I2C Addr. to (Hex)"), F("plugin_047_i2cSoilMoisture_changeAddr"), String(F("0x")) +
|
||||
String(Settings.TaskDevicePluginConfig[event->TaskIndex][0],HEX), 4);
|
||||
|
||||
addFormSeparator(string);
|
||||
addFormSeparator(2);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -59,13 +59,13 @@ boolean Plugin_048(byte function, struct EventStruct *event, String& string) {
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD: {
|
||||
|
||||
addFormTextBox(string, F("I2C Address (Hex)"), F("plugin_048_adr"), String(F("0x")) +
|
||||
addFormTextBox(F("I2C Address (Hex)"), F("plugin_048_adr"), String(F("0x")) +
|
||||
String(Settings.TaskDevicePluginConfig[event->TaskIndex][0],HEX), 4);
|
||||
|
||||
addFormNumericBox(string, F("Stepper: steps per revolution"), F("plugin_048_MotorStepsPerRevolution")
|
||||
addFormNumericBox(F("Stepper: steps per revolution"), F("plugin_048_MotorStepsPerRevolution")
|
||||
, Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
|
||||
addFormNumericBox(string, F("Stepper speed (rpm)"), F("plugin_048_StepperSpeed")
|
||||
addFormNumericBox(F("Stepper speed (rpm)"), F("plugin_048_StepperSpeed")
|
||||
, Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
|
||||
success = true;
|
||||
|
||||
+57
-12
@@ -6,10 +6,25 @@
|
||||
Additional features based on https://geektimes.ru/post/285572/ by Gerben (infernix__AT__gmail.com)
|
||||
|
||||
This plugin reads the CO2 value from MH-Z19 NDIR Sensor
|
||||
DevicePin1 - is RX for ESP
|
||||
DevicePin2 - is TX for ESP
|
||||
|
||||
Pin-out:
|
||||
Hd o
|
||||
SR o o PWM
|
||||
Tx o o AOT
|
||||
Rx o o GND
|
||||
Vo o o Vin
|
||||
(bottom view)
|
||||
Skipping pin numbers due to inconsistancies in individual data sheet revisions.
|
||||
MHZ19: Connection:
|
||||
VCC 5 V
|
||||
GND GND
|
||||
Tx ESP8266 1st GPIO specified in Device-settings
|
||||
Rx ESP8266 2nd GPIO specified in Device-settings
|
||||
*/
|
||||
|
||||
// Uncomment the following define to enable the detection range commands:
|
||||
//#define ENABLE_DETECTION_RANGE_COMMANDS
|
||||
|
||||
#define PLUGIN_049
|
||||
#define PLUGIN_ID_049 49
|
||||
#define PLUGIN_NAME_049 "Gases - CO2 MH-Z19"
|
||||
@@ -37,31 +52,56 @@ enum mhzCommands : byte { mhzCmdReadPPM,
|
||||
mhzCmdABCEnable,
|
||||
mhzCmdABCDisable,
|
||||
mhzCmdReset,
|
||||
#ifdef ENABLE_DETECTION_RANGE_COMMANDS
|
||||
mhzCmdMeasurementRange1000,
|
||||
mhzCmdMeasurementRange2000,
|
||||
mhzCmdMeasurementRange3000,
|
||||
mhzCmdMeasurementRange5000 };
|
||||
mhzCmdMeasurementRange5000
|
||||
#endif
|
||||
};
|
||||
// 9 byte commands:
|
||||
// mhzCmdReadPPM[] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
|
||||
// mhzCmdCalibrateZero[] = {0xFF,0x01,0x87,0x00,0x00,0x00,0x00,0x00,0x78};
|
||||
// mhzCmdABCEnable[] = {0xFF,0x01,0x79,0xA0,0x00,0x00,0x00,0x00,0xE6};
|
||||
// mhzCmdABCDisable[] = {0xFF,0x01,0x79,0x00,0x00,0x00,0x00,0x00,0x86};
|
||||
// mhzCmdReset[] = {0xFF,0x01,0x8d,0x00,0x00,0x00,0x00,0x00,0x72};
|
||||
// mhzCmdMeasurementRange1000[] = {0xFF,0x01,0x99,0x03,0xE8,0x00,0x00,0x00,0x7B};
|
||||
// mhzCmdMeasurementRange2000[] = {0xFF,0x01,0x99,0x07,0xD0,0x00,0x00,0x00,0x8F};
|
||||
// mhzCmdMeasurementRange3000[] = {0xFF,0x01,0x99,0x0B,0xB8,0x00,0x00,0x00,0xA3};
|
||||
// mhzCmdMeasurementRange5000[] = {0xFF,0x01,0x99,0x13,0x88,0x00,0x00,0x00,0xCB};
|
||||
// Removing redundant data, just keeping offsets [2]..[4]:
|
||||
/* It seems the offsets [3]..[4] for the detection range setting (command byte 0x99) are wrong in the latest
|
||||
* online data sheet: http://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19b-co2-ver1_0.pdf
|
||||
* According to the MH-Z19B datasheet version 1.2, valid from: 2017.03.22 (received 2018-03-07)
|
||||
* the offset should be [6]..[7] instead.
|
||||
* 0x99 - Detection range setting, send command:
|
||||
* /---------+---------+---------+---------+---------+---------+---------+---------+---------\
|
||||
* | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | Byte 8 |
|
||||
* |---------+---------+---------+---------+---------+---------+---------+---------+---------|
|
||||
* | Start | Reserved| Command | Reserved|Detection|Detection|Detection|Detection| Checksum|
|
||||
* | Byte | | | |range |range |range |range | |
|
||||
* | | | | |24~32 bit|16~23 bit|8~15 bit |0~7 bit | |
|
||||
* |---------+---------+---------+---------+---------+---------+---------+---------+---------|
|
||||
* | 0xFF | 0x01 | 0x99 | 0x00 | Data 1 | Data 2 | Data 3 | Data 4 | Checksum|
|
||||
* \---------+---------+---------+---------+---------+---------+---------+---------+---------/
|
||||
* Note: Detection range should be 0~2000, 0~5000, 0~10000 ppm.
|
||||
* For example: set 0~2000 ppm detection range, send command: FF 01 99 00 00 00 07 D0 8F
|
||||
* set 0~10000 ppm detection range, send command: FF 01 99 00 00 00 27 10 8F
|
||||
* The latter, updated version above is implemented here.
|
||||
*/
|
||||
// mhzCmdMeasurementRange1000[] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x03,0xE8,0x7B};
|
||||
// mhzCmdMeasurementRange2000[] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x07,0xD0,0x8F};
|
||||
// mhzCmdMeasurementRange3000[] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x0B,0xB8,0xA3};
|
||||
// mhzCmdMeasurementRange5000[] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x13,0x88,0xCB};
|
||||
// Removing redundant data, just keeping offsets [2], [6]..[7]:
|
||||
const PROGMEM byte mhzCmdData[][3] = {
|
||||
{0x86,0x00,0x00},
|
||||
{0x87,0x00,0x00},
|
||||
{0x79,0xA0,0x00},
|
||||
{0x79,0x00,0x00},
|
||||
{0x8d,0x00,0x00},
|
||||
#ifdef ENABLE_DETECTION_RANGE_COMMANDS
|
||||
{0x99,0x03,0xE8},
|
||||
{0x99,0x07,0xD0},
|
||||
{0x99,0x0B,0xB8},
|
||||
{0x99,0x13,0x88}};
|
||||
{0x99,0x13,0x88}
|
||||
#endif
|
||||
};
|
||||
|
||||
byte mhzResp[9]; // 9 byte response buffer
|
||||
|
||||
@@ -163,7 +203,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
|
||||
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
|
||||
String options[2] = { F("Normal"), F("ABC disabled") };
|
||||
int optionValues[2] = { ABC_enabled, ABC_disabled };
|
||||
addFormSelector(string, F("Auto Base Calibration"), F("plugin_049_abcdisable"), 2, options, optionValues, choice);
|
||||
addFormSelector(F("Auto Base Calibration"), F("plugin_049_abcdisable"), 2, options, optionValues, choice);
|
||||
byte choiceFilter = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
|
||||
String filteroptions[5] = { F("Skip Unstable"), F("Use Unstable"), F("Fast Response"), F("Medium Response"), F("Slow Response") };
|
||||
int filteroptionValues[5] = {
|
||||
@@ -172,7 +212,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
|
||||
PLUGIN_049_FILTER_FAST,
|
||||
PLUGIN_049_FILTER_MEDIUM,
|
||||
PLUGIN_049_FILTER_SLOW };
|
||||
addFormSelector(string, F("Filter"), F("plugin_049_filter"), 5, filteroptions, filteroptionValues, choiceFilter);
|
||||
addFormSelector(F("Filter"), F("plugin_049_filter"), 5, filteroptions, filteroptionValues, choiceFilter);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
@@ -246,6 +286,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
|
||||
success = true;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_DETECTION_RANGE_COMMANDS
|
||||
if (command == F("mhzmeasurementrange1000"))
|
||||
{
|
||||
_P049_send_mhzCmd(mhzCmdMeasurementRange1000);
|
||||
@@ -273,6 +314,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
|
||||
addLog(LOG_LEVEL_INFO, F("MHZ19: Sent measurement range 0-5000PPM!"));
|
||||
success = true;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
}
|
||||
@@ -413,6 +455,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
break;
|
||||
|
||||
//#ifdef ENABLE_DETECTION_RANGE_COMMANDS
|
||||
// Sensor responds with 0x99 whenever we send it a measurement range adjustment
|
||||
} else if (mhzResp[0] == 0xFF && mhzResp[1] == 0x99 && mhzResp[8] == checksum) {
|
||||
|
||||
@@ -420,6 +463,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
|
||||
addLog(LOG_LEVEL_INFO, F("Expecting sensor reset..."));
|
||||
success = false;
|
||||
break;
|
||||
//#endif
|
||||
|
||||
// log verbosely anything else that the sensor reports
|
||||
} else {
|
||||
@@ -457,7 +501,8 @@ size_t _P049_send_mhzCmd(byte CommandId)
|
||||
mhzResp[0] = 0xFF; // Start byte, fixed
|
||||
mhzResp[1] = 0x01; // Sensor number, 0x01 by default
|
||||
memcpy_P(&mhzResp[2], mhzCmdData[CommandId], sizeof(mhzCmdData[0]));
|
||||
mhzResp[5] = mhzResp[6] = mhzResp[7] = 0x00;
|
||||
mhzResp[6] = mhzResp[3]; mhzResp[7] = mhzResp[4];
|
||||
mhzResp[3] = mhzResp[4] = mhzResp[5] = 0x00;
|
||||
mhzResp[8] = _P049_calculateChecksum(mhzResp);
|
||||
|
||||
return Plugin_049_SoftSerial->write(mhzResp, sizeof(mhzResp));
|
||||
|
||||
@@ -79,7 +79,7 @@ boolean Plugin_050(byte function, struct EventStruct *event, String& string)
|
||||
optionValuesMode[3] = TCS34725_INTEGRATIONTIME_101MS;
|
||||
optionValuesMode[4] = TCS34725_INTEGRATIONTIME_154MS;
|
||||
optionValuesMode[5] = TCS34725_INTEGRATIONTIME_700MS;
|
||||
addFormSelector(string, F("Integration Time"), F("plugin_050_integrationTime"), 6, optionsMode, optionValuesMode, choiceMode);
|
||||
addFormSelector(F("Integration Time"), F("plugin_050_integrationTime"), 6, optionsMode, optionValuesMode, choiceMode);
|
||||
|
||||
byte choiceMode2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
|
||||
String optionsMode2[4];
|
||||
@@ -92,7 +92,7 @@ boolean Plugin_050(byte function, struct EventStruct *event, String& string)
|
||||
optionValuesMode2[1] = TCS34725_GAIN_4X;
|
||||
optionValuesMode2[2] = TCS34725_GAIN_16X;
|
||||
optionValuesMode2[3] = TCS34725_GAIN_60X;
|
||||
addFormSelector(string, F("Gain"), F("plugin_050_gain"), 4, optionsMode2, optionValuesMode2, choiceMode2);
|
||||
addFormSelector(F("Gain"), F("plugin_050_gain"), 4, optionsMode2, optionValuesMode2, choiceMode2);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -101,14 +101,14 @@ boolean Plugin_052(byte function, struct EventStruct *event, String& string)
|
||||
byte choiceSensor = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
|
||||
|
||||
String optionsSensor[7] = { F("Error Status"), F("Carbon Dioxide"), F("Temperature"), F("Humidity"), F("Relay Status"), F("Temperature Adjustment"), F("ABC period") };
|
||||
addFormSelector(string, F("Sensor"), F("plugin_052_sensor"), 7, optionsSensor, NULL, choiceSensor);
|
||||
addFormSelector(F("Sensor"), F("plugin_052_sensor"), 7, optionsSensor, NULL, choiceSensor);
|
||||
|
||||
/*
|
||||
// ABC functionality disabled for now, due to a bug in the firmware.
|
||||
// See https://github.com/letscontrolit/ESPEasy/issues/759
|
||||
byte choiceABCperiod = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
|
||||
String optionsABCperiod[9] = { F("disable"), F("1 h"), F("12 h"), F("1 day"), F("2 days"), F("4 days"), F("7 days"), F("14 days"), F("30 days") };
|
||||
addFormSelector(string, F("ABC period"), F("plugin_052_ABC_period"), 9, optionsABCperiod, NULL, choiceABCperiod);
|
||||
addFormSelector(F("ABC period"), F("plugin_052_ABC_period"), 9, optionsABCperiod, NULL, choiceABCperiod);
|
||||
*/
|
||||
|
||||
success = true;
|
||||
|
||||
@@ -101,8 +101,8 @@ boolean Plugin_054(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
Settings.TaskDevicePin1[event->TaskIndex] = 2;
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = Plugin_054_DMXSize;
|
||||
addFormNote(string, F("Only GPIO-2 (D4) can be used as TX1!"));
|
||||
addFormNumericBox(string, F("Channels"), F("channels"), Plugin_054_DMXSize, 1, 512);
|
||||
addFormNote(F("Only GPIO-2 (D4) can be used as TX1!"));
|
||||
addFormNumericBox(F("Channels"), F("channels"), Plugin_054_DMXSize, 1, 512);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
+12
-13
@@ -136,29 +136,28 @@ boolean Plugin_055(byte function, struct EventStruct *event, String& string)
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][1] <= 0) //Plugin_055_millisPauseTime
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = 400;
|
||||
|
||||
addFormPinSelect(string, F("GPIO → Driver#8"), F("TDP4"), (int)(Settings.TaskDevicePin[3][event->TaskIndex]));
|
||||
addFormPinSelect(F("GPIO → Driver#8"), F("TDP4"), (int)(Settings.TaskDevicePin[3][event->TaskIndex]));
|
||||
|
||||
|
||||
addFormSubHeader(string, F("Timing"));
|
||||
addFormSubHeader(F("Timing"));
|
||||
|
||||
addFormNumericBox(string, F("Chiming/Strike Time (ct)"), F("chimetime"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
addUnit(string, F("ms"));
|
||||
addFormNumericBox(F("Chiming/Strike Time (ct)"), F("chimetime"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
addUnit(F("ms"));
|
||||
|
||||
addFormNumericBox(string, F("Normal Pause Time (t)"), F("pausetime"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addUnit(string, F("ms"));
|
||||
addFormNumericBox(F("Normal Pause Time (t)"), F("pausetime"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addUnit(F("ms"));
|
||||
|
||||
addFormNote(string, F("'1=1'⇒3t, '1-1' or '11'⇒1t, '1.1'⇒⅓t, '1|1'⇒½ct"));
|
||||
addFormNote(F("'1=1'⇒3t, '1-1' or '11'⇒1t, '1.1'⇒⅓t, '1|1'⇒½ct"));
|
||||
|
||||
|
||||
addFormSubHeader(string, F("Chiming Clock"));
|
||||
addFormSubHeader(F("Chiming Clock"));
|
||||
|
||||
addFormCheckBox(string, F("Hourly Chiming Clock Strike"), F("chimeclock"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
//string += F("<TR><TD><TD>");
|
||||
string += F(" ");
|
||||
addButton(string, F("'control?cmd=chimeplay,hours'"), F("Test 1…12"));
|
||||
addFormCheckBox(F("Hourly Chiming Clock Strike"), F("chimeclock"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
//addHtml(F("<TR><TD><TD>"));
|
||||
addButton(F("'control?cmd=chimeplay,hours'"), F("Test 1…12"));
|
||||
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][2] && !Settings.UseNTP)
|
||||
addFormNote(string, F("Enable and configure NTP!"));
|
||||
addFormNote(F("Enable and configure NTP!"));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -63,11 +63,11 @@ boolean Plugin_056(byte function, struct EventStruct *event, String& string)
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
if (Plugin_056_hasTxPin(event)) {
|
||||
addFormNumericBox(string, F("Sleep time"), F("plugin_056_sleeptime"),
|
||||
addFormNumericBox(F("Sleep time"), F("plugin_056_sleeptime"),
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][0],
|
||||
0, 30);
|
||||
addUnit(string, F("Minutes"));
|
||||
addFormNote(string, F("0 = continous, 1..30 = Work 30 seconds and sleep n*60-30 seconds"));
|
||||
addUnit(F("Minutes"));
|
||||
addFormNote(F("0 = continous, 1..30 = Work 30 seconds and sleep n*60-30 seconds"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
+10
-10
@@ -94,23 +94,23 @@ boolean Plugin_057(byte function, struct EventStruct *event, String& string)
|
||||
byte addr = CONFIG(0);
|
||||
|
||||
int optionValues[8] = { 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77 };
|
||||
addFormSelectorI2C(string, F("i2c_addr"), 8, optionValues, addr);
|
||||
addFormSelectorI2C(F("i2c_addr"), 8, optionValues, addr);
|
||||
|
||||
|
||||
addFormSubHeader(string, F("7-Seg. Clock"));
|
||||
addFormSubHeader(F("7-Seg. Clock"));
|
||||
|
||||
int16_t choice = CONFIG(1);
|
||||
String options[2] = { F("none"), F("7-Seg. HH:MM") };
|
||||
addFormSelector(string, F("Clock Type"), F("clocktype"), 2, options, NULL, choice);
|
||||
addFormSelector(F("Clock Type"), F("clocktype"), 2, options, NULL, choice);
|
||||
|
||||
addFormNumericBox(string, F("Seg. for <b>X</b>x:xx"), F("clocksegh10"), CONFIG(2), 0, 7);
|
||||
addFormNumericBox(string, F("Seg. for x<b>X</b>:xx"), F("clocksegh1"), CONFIG(3), 0, 7);
|
||||
addFormNumericBox(string, F("Seg. for xx:<b>X</b>x"), F("clocksegm10"), CONFIG(4), 0, 7);
|
||||
addFormNumericBox(string, F("Seg. for xx:x<b>X</b>"), F("clocksegm1"), CONFIG(5), 0, 7);
|
||||
addFormNumericBox(F("Seg. for <b>X</b>x:xx"), F("clocksegh10"), CONFIG(2), 0, 7);
|
||||
addFormNumericBox(F("Seg. for x<b>X</b>:xx"), F("clocksegh1"), CONFIG(3), 0, 7);
|
||||
addFormNumericBox(F("Seg. for xx:<b>X</b>x"), F("clocksegm10"), CONFIG(4), 0, 7);
|
||||
addFormNumericBox(F("Seg. for xx:x<b>X</b>"), F("clocksegm1"), CONFIG(5), 0, 7);
|
||||
|
||||
addFormNumericBox(string, F("Seg. for Colon"), F("clocksegcol"), CONFIG(6), -1, 7);
|
||||
string += F(" Value ");
|
||||
addNumericBox(string, F("clocksegcolval"), CONFIG(7), 0, 255);
|
||||
addFormNumericBox(F("Seg. for Colon"), F("clocksegcol"), CONFIG(6), -1, 7);
|
||||
addHtml(F(" Value "));
|
||||
addNumericBox(F("clocksegcolval"), CONFIG(7), 0, 255);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -83,7 +83,7 @@ boolean Plugin_058(byte function, struct EventStruct *event, String& string)
|
||||
byte addr = CONFIG(0);
|
||||
|
||||
int optionValues[8] = { 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77 };
|
||||
addFormSelectorI2C(string, F("i2c_addr"), 8, optionValues, addr);
|
||||
addFormSelectorI2C(F("i2c_addr"), 8, optionValues, addr);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -86,10 +86,10 @@ boolean Plugin_059(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
String options[3] = { F("1 pulse per cycle"), F("2 pulses per cycle"), F("4 pulses per cycle") };
|
||||
int optionValues[3] = { 1, 2, 4 };
|
||||
addFormSelector(string, F("Mode"), F("qei_mode"), 3, options, optionValues, CONFIG(0));
|
||||
addFormSelector(F("Mode"), F("qei_mode"), 3, options, optionValues, CONFIG(0));
|
||||
|
||||
addFormNumericBox(string, F("Limit min."), F("qei_limitmin"), CONFIG_L(0));
|
||||
addFormNumericBox(string, F("Limit max."), F("qei_limitmax"), CONFIG_L(1));
|
||||
addFormNumericBox(F("Limit min."), F("qei_limitmin"), CONFIG_L(0));
|
||||
addFormNumericBox(F("Limit max."), F("qei_limitmax"), CONFIG_L(1));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+10
-10
@@ -74,21 +74,21 @@ boolean Plugin_060(byte function, struct EventStruct *event, String& string)
|
||||
byte addr = CONFIG(0);
|
||||
|
||||
int optionValues[8] = { 0x4D, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4E, 0x4F };
|
||||
addFormSelectorI2C(string, F("i2c_addr"), 8, optionValues, addr);
|
||||
addFormSelectorI2C(F("i2c_addr"), 8, optionValues, addr);
|
||||
|
||||
addFormCheckBox(string, F("Oversampling"), F("plugin_060_oversampling"), CONFIG(1));
|
||||
addFormCheckBox(F("Oversampling"), F("plugin_060_oversampling"), CONFIG(1));
|
||||
|
||||
addFormSubHeader(string, F("Two Point Calibration"));
|
||||
addFormSubHeader(F("Two Point Calibration"));
|
||||
|
||||
addFormCheckBox(string, F("Calibration Enabled"), F("plugin_060_cal"), CONFIG(3));
|
||||
addFormCheckBox(F("Calibration Enabled"), F("plugin_060_cal"), CONFIG(3));
|
||||
|
||||
addFormNumericBox(string, F("Point 1"), F("plugin_060_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], 0, 4095);
|
||||
string += F(" ≙ ");
|
||||
addTextBox(string, F("plugin_060_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
|
||||
addFormNumericBox(F("Point 1"), F("plugin_060_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], 0, 4095);
|
||||
addHtml(F(" ≙ "));
|
||||
addTextBox(F("plugin_060_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
|
||||
|
||||
addFormNumericBox(string, F("Point 2"), F("plugin_060_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], 0, 4095);
|
||||
string += F(" ≙ ");
|
||||
addTextBox(string, F("plugin_060_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
|
||||
addFormNumericBox(F("Point 2"), F("plugin_060_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], 0, 4095);
|
||||
addHtml(F(" ≙ "));
|
||||
addTextBox(F("plugin_060_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -106,12 +106,12 @@ boolean Plugin_061(byte function, struct EventStruct *event, String& string)
|
||||
byte addr = CONFIG(0);
|
||||
|
||||
int optionValues[16] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F };
|
||||
addFormSelectorI2C(string, F("i2c_addr"), (CONFIG(1) == 0) ? 8 : 16, optionValues, addr);
|
||||
addFormSelectorI2C(F("i2c_addr"), (CONFIG(1) == 0) ? 8 : 16, optionValues, addr);
|
||||
if (CONFIG(1) != 0)
|
||||
addFormNote(string, F("PCF8574 uses address 0x20+; PCF8574<b>A</b> uses address 0x38+"));
|
||||
addFormNote(F("PCF8574 uses address 0x20+; PCF8574<b>A</b> uses address 0x38+"));
|
||||
|
||||
String options[3] = { F("MCP23017 (Matrix 9x8)"), F("PCF8574 (Matrix 5x4)"), F("PCF8574 (Direct 8)") };
|
||||
addFormSelector(string, F("Chip (Mode)"), F("chip"), 3, options, NULL, CONFIG(1));
|
||||
addFormSelector(F("Chip (Mode)"), F("chip"), 3, options, NULL, CONFIG(1));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -71,9 +71,9 @@ boolean Plugin_062(byte function, struct EventStruct *event, String& string)
|
||||
byte addr = CONFIG(0);
|
||||
|
||||
int optionValues[4] = { 0x5A, 0x5B, 0x5C, 0x5D };
|
||||
addFormSelectorI2C(string, F("i2c_addr"), 4, optionValues, addr);
|
||||
addFormSelectorI2C(F("i2c_addr"), 4, optionValues, addr);
|
||||
|
||||
addFormCheckBox(string, F("ScanCode"), F("scancode"), CONFIG(1));
|
||||
addFormCheckBox(F("ScanCode"), F("scancode"), CONFIG(1));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -110,7 +110,7 @@ boolean Plugin_063(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormCheckBox(string, F("ScanCode"), F("scancode"), CONFIG(1));
|
||||
addFormCheckBox(F("ScanCode"), F("scancode"), CONFIG(1));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -85,7 +85,7 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string)
|
||||
byte addr = 0x39; // CONFIG(0); chip has only 1 address
|
||||
|
||||
int optionValues[1] = { 0x39 };
|
||||
addFormSelectorI2C(string, F("i2c_addr"), 1, optionValues, addr); //Only for display I2C address
|
||||
addFormSelectorI2C(F("i2c_addr"), 1, optionValues, addr); //Only for display I2C address
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -83,7 +83,7 @@ boolean Plugin_065(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormNumericBox(string, F("Volume"), F("volume"), CONFIG(0), 1, 30);
|
||||
addFormNumericBox(F("Volume"), F("volume"), CONFIG(0), 1, 30);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -71,10 +71,10 @@ boolean Plugin_066(byte function, struct EventStruct *event, String& string)
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
int optionValues[1] = { VEML6040_ADDR };
|
||||
addFormSelectorI2C(string, F("i2c_addr"), 1, optionValues, VEML6040_ADDR); //Only for display I2C address
|
||||
addFormSelectorI2C(F("i2c_addr"), 1, optionValues, VEML6040_ADDR); //Only for display I2C address
|
||||
|
||||
String optionsMode[6] = { F("40ms (16496)"), F("80ms (8248)"), F("160ms (4124)"), F("320ms (2062)"), F("640ms (1031)"), F("1280ms (515)") };
|
||||
addFormSelector(string, F("Integration Time (Max Lux)"), F("itime"), 6, optionsMode, NULL, CONFIG(1));
|
||||
addFormSelector(F("Integration Time (Max Lux)"), F("itime"), 6, optionsMode, NULL, CONFIG(1));
|
||||
|
||||
String optionsVarMap[6] = {
|
||||
F("R, G, B, W"),
|
||||
@@ -83,7 +83,7 @@ boolean Plugin_066(byte function, struct EventStruct *event, String& string)
|
||||
F("R, G, B, Color Temperature [K]"),
|
||||
F("R, G, B, Ambient Light [Lux]"),
|
||||
F("Color Temperature [K], Ambient Light [Lux], Y, W") };
|
||||
addFormSelector(string, F("Value Mapping"), F("map"), 6, optionsVarMap, NULL, CONFIG(2));
|
||||
addFormSelector(F("Value Mapping"), F("map"), 6, optionsVarMap, NULL, CONFIG(2));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -122,28 +122,28 @@ boolean Plugin_067(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormSubHeader(string, F("Measurement"));
|
||||
addFormSubHeader(F("Measurement"));
|
||||
|
||||
addFormCheckBox(string, F("Oversampling"), F("oversampling"), CONFIG(0));
|
||||
addFormCheckBox(F("Oversampling"), F("oversampling"), CONFIG(0));
|
||||
|
||||
String optionsMode[3] = { F("Channel A, Gain 128"), F("Channel B, Gain 32"), F("Channel A, Gain 64") };
|
||||
addFormSelector(string, F("Mode"), F("mode"), 3, optionsMode, NULL, CONFIG(1));
|
||||
addFormSelector(F("Mode"), F("mode"), 3, optionsMode, NULL, CONFIG(1));
|
||||
|
||||
addFormTextBox(string, F("Offset"), F("Plugin_067_offset"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3], 3), 25);
|
||||
string += F(" ↩ Tare: ");
|
||||
addCheckBox(string, F("tare"), 0); //always off
|
||||
addFormTextBox(F("Offset"), F("Plugin_067_offset"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3], 3), 25);
|
||||
addHtml(F(" ↩ Tare: "));
|
||||
addCheckBox(F("tare"), 0); //always off
|
||||
|
||||
addFormSubHeader(string, F("Two Point Calibration"));
|
||||
addFormSubHeader(F("Two Point Calibration"));
|
||||
|
||||
addFormCheckBox(string, F("Calibration Enabled"), F("Plugin_067_cal"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
addFormCheckBox(F("Calibration Enabled"), F("Plugin_067_cal"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
|
||||
addFormNumericBox(string, F("Point 1"), F("Plugin_067_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0]);
|
||||
string += F(" ≙ ");
|
||||
addTextBox(string, F("Plugin_067_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
|
||||
addFormNumericBox(F("Point 1"), F("Plugin_067_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0]);
|
||||
addHtml(F(" ≙ "));
|
||||
addTextBox(F("Plugin_067_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
|
||||
|
||||
addFormNumericBox(string, F("Point 2"), F("Plugin_067_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1]);
|
||||
string += F(" ≙ ");
|
||||
addTextBox(string, F("Plugin_067_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
|
||||
addFormNumericBox(F("Point 2"), F("Plugin_067_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1]);
|
||||
addHtml(F(" ≙ "));
|
||||
addTextBox(F("Plugin_067_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+1
-1
@@ -133,7 +133,7 @@ boolean Plugin_068(byte function, struct EventStruct *event, String& string)
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
int optionValues[2] = { 0x44, 0x45 };
|
||||
addFormSelectorI2C(string, F("i2c_addr"), 2, optionValues, CONFIG(0));
|
||||
addFormSelectorI2C(F("i2c_addr"), 2, optionValues, CONFIG(0));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+1
-1
@@ -151,7 +151,7 @@ boolean Plugin_069(byte function, struct EventStruct *event, String& string)
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
int optionValues[8] = { 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F };
|
||||
addFormSelectorI2C(string, F("i2c_addr"), 8, optionValues, CONFIG(0));
|
||||
addFormSelectorI2C(F("i2c_addr"), 8, optionValues, CONFIG(0));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -81,17 +81,17 @@ boolean Plugin_070(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormSubHeader(string, F("Clock configuration"));
|
||||
addFormNumericBox(string, F("12 o'clock LED position"), F("offset"), CONFIG(3), 0, 59);
|
||||
addFormNote(string, F("Position of the 12 o'clock LED in the strip"));
|
||||
addFormCheckBox(string, F("Thick 12 o'clock mark"), F("thick_12_mark"), CONFIG(4));
|
||||
addFormNote(string, F("Check to have 3 LEDs marking the 12 o'clock position"));
|
||||
addFormCheckBox(string, F("Clock display enabled"), F("enabled"), CONFIG(0));
|
||||
addFormNote(string, F("LED activation"));
|
||||
addFormNumericBox(string, F("LED brightness"), F("brightness"), CONFIG(1), 0, 255);
|
||||
addFormNote(string, F("Brightness level of the H/M/S hands (0-255)"));
|
||||
addFormNumericBox(string, F("Hour mark brightness"), F("marks"), CONFIG(2), 0, 255);
|
||||
addFormNote(string, F("Brightness level of the hour marks (0-255)"));
|
||||
addFormSubHeader(F("Clock configuration"));
|
||||
addFormNumericBox(F("12 o'clock LED position"), F("offset"), CONFIG(3), 0, 59);
|
||||
addFormNote(F("Position of the 12 o'clock LED in the strip"));
|
||||
addFormCheckBox(F("Thick 12 o'clock mark"), F("thick_12_mark"), CONFIG(4));
|
||||
addFormNote(F("Check to have 3 LEDs marking the 12 o'clock position"));
|
||||
addFormCheckBox(F("Clock display enabled"), F("enabled"), CONFIG(0));
|
||||
addFormNote(F("LED activation"));
|
||||
addFormNumericBox(F("LED brightness"), F("brightness"), CONFIG(1), 0, 255);
|
||||
addFormNote(F("Brightness level of the H/M/S hands (0-255)"));
|
||||
addFormNumericBox(F("Hour mark brightness"), F("marks"), CONFIG(2), 0, 255);
|
||||
addFormNote(F("Brightness level of the hour marks (0-255)"));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
+5
-5
@@ -95,13 +95,13 @@ boolean Plugin_073(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormNote(string, F("TM1637: 1st=CLK-Pin, 2nd=DIO-Pin"));
|
||||
addFormNote(string, F("MAX7219: 1st=DIN-Pin, 2nd=CLK-Pin, 3rd=CS-Pin"));
|
||||
addFormNote(F("TM1637: 1st=CLK-Pin, 2nd=DIO-Pin"));
|
||||
addFormNote(F("MAX7219: 1st=DIN-Pin, 2nd=CLK-Pin, 3rd=CS-Pin"));
|
||||
String displtype[5] = { F("TM1637 - 4 digit (colon)"), F("TM1637 - 4 digit (dots)"), F("TM1637 - 6 digit"), F("MAX7219 - 8 digit")};
|
||||
addFormSelector(string, F("Display Type"), F("plugin_073_displtype"), 4, displtype, NULL, Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
addFormSelector(F("Display Type"), F("plugin_073_displtype"), 4, displtype, NULL, Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
String displout[4] = { F("Manual"), F("Clock - Blink"), F("Clock - No Blink"), F("Date") };
|
||||
addFormSelector(string, F("Display Output"), F("plugin_073_displout"), 4, displout, NULL, Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addFormNumericBox(string, F("Brightness"), F("plugin_073_brightness"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 15);
|
||||
addFormSelector(F("Display Output"), F("plugin_073_displout"), 4, displout, NULL, Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addFormNumericBox(F("Brightness"), F("plugin_073_brightness"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 15);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ boolean Plugin_074(byte function, struct EventStruct *event, String& string)
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
int optionValues[1] = { TSL2591_ADDR };
|
||||
addFormSelectorI2C(string, F("plugin_074_i2c_addr"), 1, optionValues, TSL2591_ADDR); //Only for display I2C address
|
||||
addFormSelectorI2C(F("plugin_074_i2c_addr"), 1, optionValues, TSL2591_ADDR); //Only for display I2C address
|
||||
|
||||
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); // shortest integration time (bright light)
|
||||
@@ -83,7 +83,7 @@ boolean Plugin_074(byte function, struct EventStruct *event, String& string)
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); // longest integration time (dim light)
|
||||
|
||||
String optionsMode[6] = { F("100ms"), F("200ms"), F("300ms"), F("400ms"), F("500ms"), F("600ms") };
|
||||
addFormSelector(string, F("Integration Time"), F("plugin_074_itime"), 6, optionsMode, NULL, CONFIG(1));
|
||||
addFormSelector(F("Integration Time"), F("plugin_074_itime"), 6, optionsMode, NULL, CONFIG(1));
|
||||
|
||||
|
||||
// TSL2591_GAIN_LOW = 0x00, // low gain (1x)
|
||||
@@ -96,7 +96,7 @@ boolean Plugin_074(byte function, struct EventStruct *event, String& string)
|
||||
F("medium gain (25x)"),
|
||||
F("medium gain (428x)"),
|
||||
F("max gain (9876x)") };
|
||||
addFormSelector(string, F("Value Mapping"), F("plugin_074_gain"), 4, optionsGain, NULL, CONFIG(2));
|
||||
addFormSelector(F("Value Mapping"), F("plugin_074_gain"), 4, optionsGain, NULL, CONFIG(2));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
|
||||
@@ -368,6 +368,7 @@ To create/register a plugin, you have to :
|
||||
#define USES_C008 // Generic HTTP
|
||||
#define USES_C009 // FHEM HTTP
|
||||
#define USES_C010 // Generic UDP
|
||||
#define USES_C013 // ESPEasy P2P network
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user