Compare commits

...
182 Commits
Author SHA1 Message Date
Edwin Eefting 7ba981eaea automaticly updated release notes for v2.0.0-dev11 2017-07-17 00:55:29 +02:00
Jochen KrapfandDatuX ede5ed8b0d Plugin HX711 - Added Tare function (#419)
* Plugin HX711 - Added Tare function

* Added command "tare"
2017-07-16 19:35:27 +02:00
Jochen KrapfandDatuX b8877c53ed Plugin65 MP3 - volume updated in device menu - issue #424 (#438) 2017-07-16 19:34:04 +02:00
Edwin Eefting 296271007b added note to inverse logic to fix #318 2017-07-16 17:27:15 +02:00
Edwin Eefting d49a91c4a2 imlemented setting name, unit and password via serial. implements #317 2017-07-16 17:07:32 +02:00
Edwin Eefting 2b567f5578 gave some html logging debug-level 2017-07-16 16:50:11 +02:00
Edwin Eefting 8469188f75 Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega 2017-07-16 16:42:17 +02:00
Edwin Eefting 2409df4f5b made mdns a feature. consitent use of hostname for both mdns and dhcp client. hostname now is name_unitnumber, with spaces replaced by - 2017-07-16 16:42:07 +02:00
mvdbro c5c33cf6b6 Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into mega 2017-07-16 15:49:18 +02:00
mvdbro cea1d8b825 Revert to default ESP Easy colorscheme 2017-07-16 15:48:00 +02:00
SloMustiandDatuX 982ed4d677 added mDNS implementation (#418) 2017-07-16 15:47:34 +02:00
Edwin Eefting d424803cac more details AP mode serial output 2017-07-16 15:36:31 +02:00
SloMustiandDatuX 6cd3f514a6 Implemented a better WiFI AP naming strategy. ESP_Easy has replaced the newdevice text as the default name and now the name is used as and AP SSID (#410) 2017-07-16 15:09:54 +02:00
Edwin Eefting b5d4b96f14 Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega 2017-07-14 01:43:05 +02:00
Edwin Eefting f9ce235b32 fix HTTP chunked transfer encoding, since WebServer class doesnt support it. this fixes the 2 second delay in some browsers. (we where out of spec.) 2017-07-14 01:42:50 +02:00
Jochen KrapfandDatuX 491fa5c0a2 Added Value Logger on SD Card (#429) 2017-07-13 21:22:14 +02:00
Daniel TedenljungandDatuX 1bbbaa18f7 Renamed command to be unique. (#427) 2017-07-11 22:30:10 +02:00
Jochen KrapfandDatuX eff68b2173 Fixed multiline define bug on CRLF (#416)
Because of compiler-bug (multiline defines gives an error if file ending is CRLF) the define is striped to a single line
2017-07-07 14:42:44 +02:00
Jochen KrapfandDatuX 8b6adac269 Added Plugin for HX711 Load Cell - Request #408 (#415)
* First draft

* Added Plugin for HX711 Load Cell

* Typo
2017-07-07 14:38:54 +02:00
Jochen KrapfandDatuX e0edd56413 Added Plugin for Color Sensor VEML6040 (#412)
* First draft

* Added Plugin for Color Sensor VEML6040
2017-07-05 11:58:18 +02:00
Jochen KrapfandDatuX c95d04aa6b Added Plugin for Gesture Sensor APDS9960 (#409)
* First draft

* Work release

* work release

* Working release

Known BUG: While performing a gesture the reader function blocks rest of ESPEasy processing!!! (Feel free to fix...)
2017-07-05 11:55:12 +02:00
Jochen KrapfandDatuX 9a88269e28 Minor corrections and documentation (#404) 2017-07-05 11:53:34 +02:00
papperoneandDatuX d5847f9ea1 P010 plugin optimization (#403)
* P010 plugin optimization

optimized code in P010 plugin (probably leftovers od previous versions)

* P010 Optimization
2017-07-03 21:43:07 +02:00
mvdbro b3a75c0105 Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into mega 2017-07-02 16:07:04 +02:00
mvdbro 3ba2f38408 Update checkRAM function 2017-07-02 16:06:02 +02:00
Jochen KrapfandDatuX b455a676d8 Added Plugin for MP3 module (#402)
* Added Plugin for MP3 module

* Added [Testing] to name

* Documentation and cleanup

* Renaming to WTV020

* Documentation and corrections
2017-07-02 12:06:57 +02:00
Daniel TedenljungandDatuX e5dbb3c680 Added relay control from commands (#395) 2017-07-01 22:36:47 +02:00
Daniel TedenljungandDatuX 7d236e8564 Reading error code in other way (#394)
* Updated the way errorcodes are handled.

* Update of code after taliking with Trieb. Implemented function getBitOfInt(int reg, int pos).

* Read all bits

* Small update

Changed the way mask was defined
2017-07-01 22:36:05 +02:00
Gustavo SpadariandDatuX ae18a47bc9 Adding comments on RAW code (#386) (#393)
* Adding comments on RAW code (#386)

* Add some other comments
2017-06-29 23:39:06 +02:00
PieVoandDatuX 5dd4d49517 Update P053 (PMSx003) to support software serial and minor cleanup (#390)
* PMSx003: fix typo in description

* PMSx003: remove unused variable

* P053_PMSx003: make preparations for supporting hw and sw serial, read on plugin_read only

* P053_PMSx003: fix build and buffer reading (hw serial tested, sw not yet)

* P053_PMSx003: move serial reading to 10x sec, add debug levels, fix empty buffer read

* P053_PMSx003: drop log message in read, already posted as EVENT
2017-06-28 22:29:18 +02:00
Jochen KrapfandDatuX d708d6a057 Check plugin-array size on init - issue #119 (#389)
very nice! another issue fixed:)
2017-06-27 23:57:59 +02:00
imthemichiandDatuX c3db03ea5e Plugin_008-RFID extended with wiegand 34-bits and key-pad (#387)
* Plugin_008-RFID extended with wiegand 34-bits and key-pad (4-bits per key) support

* removed millis from interupt-handler and volatile from keyBuffer because of high IRAM usage
2017-06-26 10:07:02 +02:00
mvdbroandGitHub b65812ebf3 Merge pull request #385 from jkDesignDE/menu3
Reenabled javascript for device-selector
2017-06-24 09:49:15 +02:00
mvdbroandGitHub 698299f918 Merge pull request #384 from papperone/mega
P038 - optimization
2017-06-24 09:49:00 +02:00
JK 277d12205d Reenabled javascript for device-selector 2017-06-23 18:00:20 +02:00
papperone 52b3c2e962 P038 - optimization
deleted unneded parsing line in the WRITE function and used only the
event->Par1/5 variables already available
2017-06-22 22:41:30 +02:00
mvdbroandGitHub f6cadc43f3 Merge pull request #383 from jkDesignDE/menu2
Fine tuning of CSS and menu
2017-06-22 18:57:03 +02:00
mvdbroandGitHub e393d66283 Merge pull request #382 from tedenda/C011_Rename_constants
Renamed constants
2017-06-22 18:56:27 +02:00
JK 10e33de018 Fine tuning of CSS and menu 2017-06-22 13:20:13 +02:00
tedenda 842dc38805 Missed one... 2017-06-22 13:07:27 +02:00
tedenda 52ef5c06fd Renamed Prefix from P011 to C011 2017-06-22 12:57:41 +02:00
Edwin Eefting 1c63589b3d upgraded IRremoteESP8266 from v1.0.2 to v1.2.0. fixes #188 2017-06-21 17:17:21 +02:00
Jochen KrapfandDatuX 3e230310b9 Step back to style-based-css for speed up + pimp menu (#376)
* Renaming

* Fixed DEVICES_MAX for testing and dev

* Experiments with delivering HTML

* Step back to style-based-css for speed up

* pimp menu

* pimp menu
2017-06-21 01:52:39 +02:00
SloMustiandDatuX ce249aaa4a fixed deep sleep, such that it can be enabled from Rules (#375) 2017-06-21 01:50:28 +02:00
Jochen KrapfandDatuX bd216674d4 Fixed DEVICES_MAX for testing and dev (#374) 2017-06-20 13:16:27 +02:00
Edwin Eefting 32c4b1d614 add caching headers to static content 2017-06-20 00:30:59 +02:00
Edwin Eefting 1847746077 serial now no longer resonds to empty commands 2017-06-19 22:41:19 +02:00
Edwin Eefting 56741b425c fix #372 2017-06-19 22:31:13 +02:00
DatuXandGitHub 4f3a8e6acb Update issue_template.md 2017-06-19 21:10:54 +02:00
DatuXandGitHub f40d8c3cf4 Update issue_template.md 2017-06-19 21:10:35 +02:00
mvdbroandGitHub d7a3c74ad9 Merge pull request #370 from jkDesignDE/TTP229
Added Plugin for Touch KeyPad Chip TTP229
2017-06-19 20:02:17 +02:00
JK b5049cd9ca Added Plugin for Touch KeyPad Chip TTP229 2017-06-19 19:42:38 +02:00
mvdbroandGitHub 55536cc4b3 Merge pull request #366 from papperone/mega
Fixed Broken P038
2017-06-19 19:41:00 +02:00
mvdbroandGitHub cbbec517d6 Merge pull request #364 from jkDesignDE/ChunkedSend
Send web page as junked data - issue #352
2017-06-19 19:39:07 +02:00
mvdbroandGitHub db2624d49d Merge pull request #368 from jkDesignDE/CRLF
Accept CR and LF at serial commands
2017-06-19 19:33:27 +02:00
JK d7116735e9 First draft 2017-06-19 15:19:49 +02:00
papperone 43ba235e68 reverted some changes due to bug fixed in the "webserver.ino #348" 2017-06-18 23:10:50 +02:00
papperone 2c3c8f6e0d Merge remote-tracking branch 'refs/remotes/letscontrolit/mega' into mega 2017-06-18 23:07:51 +02:00
JK 6dc816869f Merge remote-tracking branch 'base/mega' into CRLF 2017-06-18 06:57:40 +02:00
mvdbro 5fff3c6ce7 Added pin state buffer table page (mainly for debugging) 2017-06-17 22:51:34 +02:00
JK fe85b0908c Accept CR and LF at serial commands 2017-06-17 22:36:29 +02:00
papperone 612742f669 p038
BugFixing
2017-06-17 18:55:55 +02:00
mvdbro 8d2303db5f Fix default controller settings (#360) 2017-06-17 16:41:52 +02:00
JK 97b90a09db Send web page as junked data 2017-06-16 09:19:10 +02:00
papperone dcdf095575 Fixed Broken P038
Fixed GUI of plugin adding correct GPIO request
Fixed code for "NeoPixelAll" command
Tested on ESP8266 and WemosD1Mini with various WS2812 configuration
hardware
2017-06-16 07:42:19 +02:00
JK 9ecfce472d First draft 2017-06-16 02:52:49 +02:00
Jochen KrapfandDatuX 20e5bc0081 Write default CSS to SPIFFS on boot (#357)
* Write CSS to SPIFFS on boot

* Fixed DEFINE bug

In CPPCHECK:
-> error: 'CPLUGIN_ID_002' was not declared in this scope

@mvdbro: please take a look
2017-06-15 09:06:14 +02:00
Edwin Eefting 5136d4757c accidently enabled FEATURE_ARDUINO_OTA 2017-06-12 23:03:13 +02:00
Edwin Eefting 2729e341c8 saved ~800 bytes ram in handle_devices(), issue #352. left old code commented for reference, in case i created bugs. will remove later 2017-06-12 22:55:42 +02:00
Jochen KrapfandDatuX 6d0399c6c7 Increase DEVICES_MAX for more testing and dev plugins (#353) 2017-06-12 13:25:31 +02:00
krikkandDatuX 72d07bc303 implemented a measurement type selection to retain backward compability to Domoticz... hope this works... (#351) 2017-06-11 21:58:18 +02:00
Daniel TedenljungandDatuX c55bb28038 Senseair update (#333)
* New company name

* New sensor: Relay Status

* New sensor: Temperature adjustment

* Small update of log messages

* Some renaming
2017-06-11 21:57:20 +02:00
Jochen KrapfandDatuX 0a746d017e Added plugins for HT16K33 LED matrix driver and key pad scanner (#328)
* First draft

* work release

* work release

* Work release

* Work release

* Work release

* Work release

* rename file

* Work release (not working)

* Rework with library

* Working LED plugin with Clock

* Added plugins for HT16K33 LED matrix driver and key pad scanner

* Fixed typing of Arduino.h

* Documentation
2017-06-11 21:56:07 +02:00
mvdbro de4517f614 Fix incorrect ADC GPIO display 2017-06-11 09:39:10 +02:00
mvdbro 0dcd89a653 MQTT Controller enable/disable fix (#287) 2017-06-10 22:52:01 +02:00
mvdbro f70970c6f3 Enlarge MQTT buffer for Domoticz MQTT controller 2017-06-10 22:34:55 +02:00
mvdbro 4d28d2b837 Fix Domoticz helper plugin #330 2017-06-10 22:31:55 +02:00
Jochen KrapfandDatuX b63e76adfe Fixed issue #348 (#349) 2017-06-10 14:31:59 +02:00
Jochen KrapfandDatuX 77eedf5d6c Added Plugin _P062_MPR121_KeyPad (#346) 2017-06-10 14:28:19 +02:00
Jochen KrapfandDatuX 01ff98be05 Fixed issues #308 #305 (#345)
* Formula option for  _P013_HCSR04 plugin #343

* First draft

* Fixed issues #308 #305
2017-06-10 14:27:32 +02:00
Jochen KrapfandDatuX 6222041a30 Formula option for _P013_HCSR04 plugin issue #343 #313 (#344)
* Formula option for  _P013_HCSR04 plugin #343

* Minor fixes to #313
2017-06-10 14:25:07 +02:00
Jochen KrapfandDatuX 302e0d7fa7 Added Plugin _P060_MCP3221 (#342)
* First draft

* Working release
2017-06-10 13:57:32 +02:00
krikkandDatuX 894e9c3ff6 added local ip to sysinfo plugin, due to limitation of return type float, i had to split up the ip in its octets... fixes issue #228 (#341) 2017-06-10 13:56:15 +02:00
Jochen KrapfandDatuX 66bda6d531 Added Plugin _P061_KeyPad (#340) 2017-06-10 13:53:46 +02:00
krikkandDatuX f3c7c68248 seconds were displayed without leading zero issue #337 (#338) 2017-06-10 13:52:28 +02:00
krikkandDatuX 093767f2b1 delay option should be displayed even if the SendDataOption is false, because the delay option also controls the refresh rate of the oled display... fixes issue #336 (#339) 2017-06-10 13:31:16 +02:00
Jochen KrapfandDatuX 50f6c403e8 Added Plugin for Quadrature Encoder Interface (Rotary Encoder) (#335)
* First draft

* Functional QEI plugin

* Corrected spelling of limits.h
2017-06-10 13:11:49 +02:00
Edwin Eefting 3c41155ee4 backup 2017-06-06 23:57:23 +02:00
Edwin Eefting dcc2dbf0c6 converted all commands to python 2017-06-06 23:26:00 +02:00
Edwin Eefting fd1da876a4 dont want wifi passwords on github 2017-06-06 23:03:53 +02:00
Edwin Eefting 93fc1b6140 dont want wifi passwords on github 2017-06-06 23:01:26 +02:00
Edwin Eefting 80fb17ca05 esptesting framework 2017-06-06 22:58:21 +02:00
Edwin Eefting ee0069ffa4 Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega 2017-06-06 19:46:12 +02:00
Edwin Eefting b1bd7d63f6 working on test framework 2017-06-06 19:46:01 +02:00
DatuXandGitHub ef8059cf56 Update README.md 2017-06-06 15:15:29 +02:00
Edwin Eefting 8d246947c1 Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega 2017-06-06 00:32:28 +02:00
Edwin Eefting 8bcf29fa11 Fixed variable naming bug in FEATURE_ADC_VCC 2017-06-06 00:32:23 +02:00
elucas2uyandDatuX 4b900daa67 FIX Pass and Index on handle_controllers() (#331)
* FIX Pass and Index on handle_controllers()

* Update WebServer.ino
2017-06-05 17:43:53 +02:00
Edwin Eefting a84567c14e Fixed crashbug in email notification 2017-06-04 22:36:02 +02:00
Edwin Eefting d4420b9e36 better rtc error logging 2017-06-04 12:15:51 +02:00
Daniel TedenljungandDatuX 6daa9a1e3c Fixed decimal values (#329) 2017-06-04 01:51:38 +02:00
Edwin Eefting 6a4f8a6942 added option do deepsleep on connection failures. had to change boot order a bit, so the rebooted/warmboot message is the first one now. (this also makes more sense). issue #206 2017-06-02 17:56:45 +02:00
Edwin Eefting 41974d12e5 prevent recursion when processing background tasks. might help with issue #117 2017-06-02 17:05:41 +02:00
Edwin Eefting ea5168c08a large changes to wifi handling. code cleanup, more efficent connecting, only one connect retry in deepsleep. better serial logging for connections and APmode. always enable ap mode when wifi is disconnected 2017-06-02 02:02:19 +02:00
Edwin Eefting d07bb3574a started working on regression testing scripts for The Rig 2017-06-01 20:43:47 +02:00
Edwin Eefting fb83badfce cleaned up RTC initialisation. fixed some fuzzy issues after flashing/factory reset. improved flash-counter messages and added powercycle tips 2017-06-01 01:38:19 +02:00
Jochen KrapfandDatuX 1a9eedc6d6 Added _P056_SDS011-Dust (#324)
* Added _P056_SDS011-Dust

* removed SDS-lib as submodule

* added SDS-lib as files
2017-05-31 01:02:04 +02:00
Jochen KrapfandDatuX b26b4a1a93 Added _P055_Chiming (#323) 2017-05-31 00:57:33 +02:00
krikkandDatuX f3e7dffec4 changed the ina219 plugin so that is always sends 3 values, voltage, current, power... like a normal plugin should do... (#325)
also added measurement range selection
2017-05-31 00:54:13 +02:00
Jochen KrapfandDatuX 9341bde0da Added _P054_DMX512 (#322) 2017-05-31 00:53:35 +02:00
Edwin Eefting e10a6e6f55 automaticly updated release notes for v2.0.0-dev10 2017-05-29 22:53:54 +02:00
krikkandDatuX f0ed209ba6 reverted change, this fix seems to have exactly opposite outcome than expected... with the fix applied i get errors, without is i get no errors... (#320) 2017-05-29 22:31:28 +02:00
Jochen KrapfandDatuX 2672558bfe Rework of plugin ADC (#319)
Minor changes of ADS1115
2017-05-29 22:30:14 +02:00
DatuXandGitHub ffe2f3f775 Update README.md 2017-05-28 23:52:55 +02:00
Edwin Eefting 92816f1a9f automaticly updated release notes for v2.0.0-dev9 2017-05-28 15:16:00 +02:00
Edwin Eefting 43ef90f688 also distribute ESP8285 binaries 2017-05-28 15:15:06 +02:00
Jochen KrapfandDatuX 2c6096dd31 Rework of plugin ADS1115 (#315)
* Fixed some minor HTML syntax bugs

* Fixed some minor HTML syntax bugs

* Rework of plugin ADS1115
2017-05-28 12:06:52 +02:00
krikkandDatuX 1cefa5eb1b AM2320: negative temperature fix... (#312)
* switched the library, now uses a library which correctly handles negative temperatures

* minor change
2017-05-27 17:55:13 +02:00
DatuXandGitHub a8e39b1899 Update README.md 2017-05-27 16:45:17 +02:00
DatuXandGitHub b1a47e4c3a Update README.md 2017-05-27 16:08:19 +02:00
Jochen KrapfandDatuX b7d881d136 Fixed some minor HTML syntax bugs (#310)
* Fixed some minor HTML syntax bugs

* Fixed some minor HTML syntax bugs
2017-05-26 11:14:06 +02:00
Alex Schwantes 67c3a166f5 Implemented use of addFormSelector methods to _P004_Dallas plugin.
Changed the device select box to show the one wire address for each connected sensor instead of just a number.
Added a blank option to the device address select box so that in the event that multiple devices are present and the configured device is not currently available, the select box will be blank instead of selecting a different device.
2017-05-23 03:41:13 +02:00
Jochen KrapfandDatuX 060b72e88b Pimp device-GUI and optimized HTML (#306)
* First draft

* work release

* work release (not working)

* optimized css

* Pimp device-GUI and optimized HTML

* Handle cppcheck error

* Round help button

* Minor bug fixes
2017-05-22 23:31:58 +02:00
Edwin Eefting 36550511f5 fixing cpp check 2017-05-18 23:00:29 +02:00
Edwin Eefting fb8188b14b fixing cpp check 2017-05-18 22:44:20 +02:00
Edwin Eefting 436564ba51 fixing cpp check 2017-05-18 22:39:48 +02:00
Edwin Eefting 9016f1b53e fixing cpp check 2017-05-18 22:25:46 +02:00
Edwin Eefting 0404a871f2 fixed a few out of bounds bugs in Misc.ino _P023_OLED.ino _P035_IRTX.ino _P037_MQTTImport.ino with cppcheck. also added cppcheck to travis to prevent such cases in the future 2017-05-18 22:21:01 +02:00
krikkandDatuX 1413c92678 do a dns lookup on every request, solves issue #261 (#302) 2017-05-16 21:13:06 +02:00
PieVoandDatuX 28208ac7a2 Plantower (#300)
* + pmsx005: add all values as output

* - PMSx005: remove additional measurements from values

* + PMSx005: fix return values for plugin function

* * PMSx003: rename filename to match devices (PMS3003, 5003, 7003, A003)

* * PMSx003: fix valuecount and prevent sending to controllen when nothing recveid yet

* * PMSx003: rename _P050 to _P053

* + PMSx003: add PLUGIN_BUILD_TESTING

* - PMSx003: remove old _P050 that made place for _P053
2017-05-14 19:47:04 +02:00
DatuXandGitHub 168a2c343c Update CONTRIBUTING.md 2017-05-14 11:53:06 +02:00
Jochen KrapfandDatuX a873e920d4 Fixed rules bug #297 (#299) 2017-05-14 11:42:27 +02:00
beicandDatuX 10838d544c Some little description corrections (#297) 2017-05-13 23:45:38 +02:00
Daniel TedenljungandDatuX ab48fc0dfd New look on Tools page (#296)
* New look on Tools page

* Smal adjustment
2017-05-13 23:01:15 +02:00
Jochen KrapfandDatuX bcf6521ef9 Added HTML templates for customization (#290)
* First draft of templates

* Added templates for customization

* Fixed dept_onchange(frmselect)

* Moved javascript to sendWebPage()

* moved javascript to template var

* Preparation for selected menus

and bugfix if 2 vars are stand near together

* removed libs from prev. commit

* rework of menu

* Some cleanup
2017-05-13 22:56:28 +02:00
krikkandDatuX 6f8d7d1ada i don't like hidden features, added a json button to the tools menu, next to the advanced button (#292) 2017-05-13 09:37:03 +02:00
Daniel TedenljungandDatuX c6f03551c5 addSubmitButton function added (#289) 2017-05-11 15:13:48 +02:00
Edwin Eefting b2a9679488 nicer sleep messages 2017-05-11 02:18:45 +02:00
Edwin Eefting b66d983060 bugfix in rtc checksum 2017-05-11 01:59:27 +02:00
Edwin Eefting 2b16ddedbf reboot and wifidisconnect should be handled by / 2017-05-11 01:54:44 +02:00
Daniel TedenljungandDatuX dbd89deb7b GUI touchup on Tools (#286)
* GUI touchup on Tools

I added some space between settings-firmware and firmware-filesystem to
make it look nicer (my opinion).

* Implemented addButton function
2017-05-11 00:40:30 +02:00
Jochen KrapfandDatuX 6c52721ed1 Limits to NumericBox and a bit of security to PasswordBox (#281)
* Limits to NumericBox and a bit of security to PasswordBox

* Limits to NumericBox and a bit of security to PasswordBox

Password handling: Deliver "*****" to password box accept changes if not equal to "*****"

* solved merge conflicts
2017-05-11 00:39:33 +02:00
Blair ThompsonandDatuX 03fbe8fcca Added Par4 and Par5 Variables (#248)
I am working on an RGBW lightbulb plugin and 3 variables are not enough
to control it.  Rather than add variables in the plugin (like neopixel
does) i think it is better to add them to EventStruct.  I only needed 4,
but neopixel uses 5
2017-05-11 00:14:28 +02:00
krikkandDatuX 9e0af20343 DHT plugin fix 'NaN' issue (#285)
issue https://github.com/letscontrolit/ESPEasy/issues/284 seems valid to me, implemented...
2017-05-10 23:40:26 +02:00
Daniel TedenljungandDatuX aa0b4d0fce P052: More descriptive log messages (#283)
* Better log messages

* Missed semicolon...
2017-05-10 23:38:47 +02:00
krikkandDatuX a9f6605065 addHelpButton Function and a new Help Button for the Rules and Hardware Page (#282) 2017-05-10 23:36:39 +02:00
krikkandDatuX 26b073ba34 make the Settings - Save. Filename more descriptive... (#273)
* make the Settings - Save. Filename more descriptive, didn't like this also. solves issue: #241

* added getDateString + getTimeString + getDateTimeString Functions and replaced dublicate code with the new functions...

* more comments :)
2017-05-10 23:34:40 +02:00
Jochen KrapfandDatuX 27bba1b628 Fixed readUserVarFromRTC() #265 (#280)
Uses checksum to verify user var buffer and fill with zero
2017-05-09 20:50:15 +02:00
Jochen KrapfandDatuX 6131ebca73 Replaced HTML code with addFormSelector() in all plugins (#278)
and added function addFormSelectorI2C()

Note: not all plugins can be tested :(
2017-05-09 20:47:05 +02:00
krikkandDatuX 01b42a6dfb addFormNumeric with min and max & More Form-Function replacements (#272)
* add getFormItemFloat, because we have some float input also

* more form-functions optimizations...

* addFormNumeric with min and max parameters

* ...and more formFunctions replacements

* ...and more formFunctions replacements

* ...and more formFunctions replacements

* ...and more formFunctions replacements

* ...so first round done...  will do another round when addFormSelector is merged...

* and a few controller text boxes can be replaced also...

* one char to much...
2017-05-09 00:19:03 +02:00
Jochen KrapfandDatuX 23be929f72 Preliminary final draft of bugfix #264 (#271)
Group name can be changed during merge in... ;)
2017-05-09 00:16:01 +02:00
Jochen KrapfandDatuX b536770a07 Added function addFormSelector (#270)
* Added function addFormSelector

usage:
        const String options[] = { F("DHT 11"), F("DHT 22"), F("DHT 12") };
        int indices[] = { 11, 22, 12 };

        addFormSelector(string, F("DHT Type"), F("plugin_005_dhttype"), 3, options, indices, choice );

or with zero based index:
        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 );

+ minor HTML fixes in addFormSubHeader and addFormSeparator

* additional params to addSelector()

* replaced more HTML with Selector functions
2017-05-09 00:12:41 +02:00
Daniel TedenljungandDatuX 792982262b Updated wrong plugin number. (#269)
* Moving plugin from playground

I am now moving this plugin from playground to main repo. It is tested
for long time and works fine.

* Forgot #endif

* Exclude readme.

* Wrong plugin number
2017-05-05 00:12:43 +02:00
krikkandDatuX 541d50e6bb bug fix wrong return type + form function fixes (#266)
* seems to be a type, but return type must be int!

* for form-function optimizations

* even more form-functions....

* even more form-functions + type fix

* lots of form-functions...
2017-05-05 00:05:33 +02:00
Bartlomiej ZimonandEdwin Eefting c8d88140f7 Add backup Wifi network to Settings command 2017-05-04 16:54:38 +02:00
Bartlomiej ZimonandEdwin Eefting d3fdf27746 Add WifiSSID2,WifiKey2 commands 2017-05-04 16:53:53 +02:00
Bartlomiej ZimonandEdwin Eefting afb6860156 Push ProtocolIndex and ControllerIndex into CPLUGIN_WEBFORM_SAVE/LOAD 2017-05-04 16:52:42 +02:00
Bartlomiej ZimonandEdwin Eefting 48563bade6 Custom Controller Settings - add controller index 2017-05-04 16:50:47 +02:00
Bartlomiej ZimonandEdwin Eefting 017019e122 - Misc: typo 2017-05-04 16:06:32 +02:00
Edwin Eefting 8e0d78af7b Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega 2017-05-04 15:46:48 +02:00
Edwin Eefting 66531d46bd comments. checkudp only in backgroundtasks() 2017-05-04 15:46:38 +02:00
tedendaandDatuX 83dbb63d13 Moving plugin from Playground into main repo. (#262)
* Moving plugin from playground

I am now moving this plugin from playground to main repo. It is tested
for long time and works fine.

* Forgot #endif
2017-05-04 01:21:09 +02:00
krikkandDatuX 771f981c13 replaced static html code with the new addForm* Functions 2017-05-03 23:10:44 +02:00
JKandDatuX 9d5afd1e2a Fixed #196 and rework of IDX display 2017-05-03 11:52:26 +02:00
DatuXandGitHub 33ac272804 Update issue_template.md 2017-05-02 23:53:35 +02:00
DatuXandGitHub 30a1e4c7c3 Update README.md 2017-05-02 21:24:29 +02:00
Jochen KrapfandDatuX 1d97f08b34 Added addForm*-functions for easy web-interface and pimp GUI (#259)
* first draft

* work release

* work release

* work release

* work release

* work release

* work release

* Added addForm*-functions for easy web-interface and pimp GUI

Changes many HTML-code to function calls for less code and more readability. More changes are coming soon.
Some groupings in Web-Interface.
2017-05-02 21:10:54 +02:00
Edwin Eefting 752a741e60 input box fix on setting pages 2017-05-02 20:30:20 +02:00
krikkandDatuX 9eaf88abad another fix to http advanced...
never do code changes without testing it... fixed http get, but broke http post, now its working again
2017-05-02 08:39:22 +02:00
krikkandDatuX f5ffcf5454 use the new addCheckBox function and better display of device config page 2017-05-02 02:11:58 +02:00
Edwin Eefting e8c5a02ead timer boundschecker was off by one. fixed memanalyser total 2017-05-02 01:27:53 +02:00
Edwin Eefting 5c9d00c0a9 publish MQTT Connected message 2017-05-02 00:47:04 +02:00
Edwin Eefting 9b8d5bba4c cosmetic buildlog fix 2017-05-02 00:18:49 +02:00
Edwin Eefting 5f8e2a70d0 more details in memory analyser. run memory analyser via Travis 2017-05-02 00:10:03 +02:00
Edwin Eefting 19b1316205 fixed issue #253 (memory leaks/crashes) 2017-05-01 23:00:24 +02:00
krikkandDatuX b9f47d3cf2 i2c Temperatur & Humidity Sensor Am2320 (#251)
* add support for i2c am2320 temperature and humidity sensor based on this https://github.com/hibikiledo/AM2320 library

* add i2cScanner detection of AM2320 Sensor

* minor
2017-05-01 11:58:13 +02:00
krikkandDatuX 75067cd33f http advanced controller, correct passing of hostname (#250)
* http advanced controller, correct passing of hostname

fixes an error reported by mikrom in the forum: https://www.letscontrolit.com/forum/viewtopic.php?f=4&t=2973

* http request must close mit double newline...

wrong newline in case of get request without body
the request ends with a double newline, each in the form of a carriage return followed by a line feed
2017-04-30 12:54:37 +02:00
JKandDatuX 25477a1232 solved my commit mismatch 2017-04-27 11:20:44 +02:00
JKandDatuX 4b9b3f5a37 fine tuning of status LED and pimp hardware web site 2017-04-27 11:20:44 +02:00
JKandDatuX c0d147f3df added checkbox for status LED inversed 2017-04-27 11:20:44 +02:00
JKandDatuX 228f782762 added functions addCheckBox and addNumericBox 2017-04-27 11:04:52 +02:00
Edwin Eefting e952bb8731 cleaned up messagedelay: use the same function everywhere. and do serial processing as well during the messagedelay 2017-04-24 22:19:26 +02:00
137 changed files with 15566 additions and 3812 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ Also there are more people on the forum that can help you with support.
* Dont combine a lot of different stuff in one huge pull request.
* Incomplete or unstable plugins should have a PLUGIN_BUILD_DEV ifdef around them.
* Incomplete or unstable plugins should have a PLUGIN_BUILD_DEV #ifdef around them. Also add [DEVELOPMENT] to the name.
* New plugins that seem to be working correctly should have a PLUGIN_BUILD_TESTING around until they are tested enough.
+4
View File
@@ -1,6 +1,10 @@
**NOTE: This is not a support forum! For questions and support go here: https://www.letscontrolit.com/forum/viewforum.php?f=1**
### Steps to reproduce
How can we trigger this problem?
Does the problem presist after powering off and on? (just resetting isnt enough sometimes)
### Expected behavior
Tell us what should happen?
+2
View File
@@ -2,3 +2,5 @@
.clang_complete
.gcc-flags.json
.piolibdeps
lib/readme.txt
+21 -3
View File
@@ -1,15 +1,33 @@
language: python
python:
- '2.7'
- '2.7'
#we want a newer cppcheck, so use trusty
dist: trusty
sudo: false
cache:
directories:
- "~/.platformio"
- "./.pioenvs"
addons:
apt:
packages:
- cppcheck
install:
- pip install -U platformio
- pip install -U platformio
script:
- platformio run
- cppcheck --enable=warning src/*.ino -q --force -I src --include=src/ESPEasy.ino --error-exitcode=1
- ./memanalyzer.py ~/.platformio/packages/toolchain-xtensa/bin/xtensa-lx106-elf-objdump
- platformio run -s
before_deploy:
- ./before_deploy
+30 -1
View File
@@ -2,13 +2,42 @@
Build status: [![Build Status](https://travis-ci.org/letscontrolit/ESPEasy.svg?branch=mega)](https://travis-ci.org/letscontrolit/ESPEasy)
Introduction and wiki: https://www.letscontrolit.com/wiki/index.php/ESPEasy#Introduction
This is the development branch for the next upcoming release (2.0.0). This is also known as ESPEasyMega.
Check here to learn how to use this branch and help us improving ESPEasy: http://www.letscontrolit.com/wiki/index.php/ESPEasy#Source_code_development
## Versions
* v2.0.0-devX: these are the current development releases. use these if you want bleeding edge features, or if you want to help us testing and developing. new release every month.
* v2.0.0-betaX: as soon as we think its stable/complete enough for real testing, we will start numbering beta's.
* v2.0.0-rcX: release candidates (probably stable)
* v2.0.0: This will be the first stable release. After this we will use more standard numbering. Next bugfix release will probably be 2.0.1.
## Firmware binary releases
Binary development releases are here: https://github.com/letscontrolit/ESPEasy/releases
Details and discussion are on the Experimental forum: http://www.letscontrolit.com/forum/viewtopic.php?f=18&t=2257&p=13600#p13600
Depending on your needs, we release different types of files.
For version 2.0.0-dev9 and higer:
Firmware name | Hardware | Included plugins |
-------------------------------------|-------------------------|-----------------------------|
ESPEasy_v2.0.0-dev9_dev_1024.bin | ESP8266 with 1Mb flash | Stable + Test + Development |
ESPEasy_v2.0.0-dev9_test_1024.bin | ESP8266 with 1Mb flash | Stable + Test |
ESPEasy_v2.0.0-dev9_normal_1024.bin | ESP8266 with 1Mb flash | Stable |
ESPEasy_v2.0.0-dev9_dev_4096.bin | ESP8266 with 4Mb flash | Stable + Test + Development |
ESPEasy_v2.0.0-dev9_test_4096.bin | ESP8266 with 4Mb flash | Stable + Test |
ESPEasy_v2.0.0-dev9_normal_4096.bin | ESP8266 with 4Mb flash | Stable |
ESPEasy_v2.0.0-dev9_dev_8285.bin | ESP8285 | Stable + Test + Development |
ESPEasy_v2.0.0-dev9_test_8285.bin | ESP8285 | Stable + Test |
ESPEasy_v2.0.0-dev9_normal_8285.bin | ESP8285 | Stable |
## More info
Details and discussion are on the Experimental forum: https://www.letscontrolit.com/forum/viewforum.php?f=18
We're also on IRC: #ESPEasy @freenode
+3
View File
@@ -7,12 +7,15 @@ echo "Creating release archives for $VERSION ..."
cp .pioenvs/normal_1024/firmware.bin dist/"ESPEasy_$VERSION""_normal_1024.bin"
cp .pioenvs/normal_4096/firmware.bin dist/"ESPEasy_$VERSION""_normal_4096.bin"
cp .pioenvs/normal_8285/firmware.bin dist/"ESPEasy_$VERSION""_normal_8285.bin"
cp .pioenvs/test_1024/firmware.bin dist/"ESPEasy_$VERSION""_test_1024.bin"
cp .pioenvs/test_4096/firmware.bin dist/"ESPEasy_$VERSION""_test_4096.bin"
cp .pioenvs/test_8285/firmware.bin dist/"ESPEasy_$VERSION""_test_8285.bin"
cp .pioenvs/dev_1024/firmware.bin dist/"ESPEasy_$VERSION""_dev_1024.bin"
cp .pioenvs/dev_4096/firmware.bin dist/"ESPEasy_$VERSION""_dev_4096.bin"
cp .pioenvs/dev_8285/firmware.bin dist/"ESPEasy_$VERSION""_dev_8285.bin"
#create a source structure that is the same as the original ESPEasy project (and works with the howto on the wiki)
rm -rf dist/Source 2>/dev/null
+245
View File
@@ -1,3 +1,248 @@
-----------------------------
Changes in release v2.0.0-dev11
-----------------------------
Release date: Mon Jul 17 00:55:29 CEST 2017
Daniel Tedenljung (5):
Fixed decimal values (#329)
Senseair update (#333)
Reading error code in other way (#394)
Added relay control from commands (#395)
Renamed command to be unique. (#427)
DatuX (4):
Update README.md
Update README.md
Update issue_template.md
Update issue_template.md
Edwin Eefting (27):
automaticly updated release notes for v2.0.0-dev10
cleaned up RTC initialisation. fixed some fuzzy issues after flashing/factory reset. improved flash-counter messages and added powercycle tips
started working on regression testing scripts for The Rig
large changes to wifi handling. code cleanup, more efficent connecting, only one connect retry in deepsleep. better serial logging for connections and APmode. always enable ap mode when wifi is disconnected
prevent recursion when processing background tasks. might help with issue #117
added option do deepsleep on connection failures. had to change boot order a bit, so the rebooted/warmboot message is the first one now. (this also makes more sense). issue #206
better rtc error logging
Fixed crashbug in email notification
Fixed variable naming bug in FEATURE_ADC_VCC
working on test framework
esptesting framework
dont want wifi passwords on github
dont want wifi passwords on github
converted all commands to python
backup
saved ~800 bytes ram in handle_devices(), issue #352. left old code commented for reference, in case i created bugs. will remove later
accidently enabled FEATURE_ARDUINO_OTA
fix #372
serial now no longer resonds to empty commands
add caching headers to static content
upgraded IRremoteESP8266 from v1.0.2 to v1.2.0. fixes #188
fix HTTP chunked transfer encoding, since WebServer class doesnt support it. this fixes the 2 second delay in some browsers. (we where out of spec.)
more details AP mode serial output
made mdns a feature. consitent use of hostname for both mdns and dhcp client. hostname now is name_unitnumber, with spaces replaced by -
gave some html logging debug-level
imlemented setting name, unit and password via serial. implements #317
added note to inverse logic to fix #318
Gustavo Spadari (1):
Adding comments on RAW code (#386) (#393)
JK (7):
First draft
Send web page as junked data
Accept CR and LF at serial commands
First draft
Added Plugin for Touch KeyPad Chip TTP229
Fine tuning of CSS and menu
Reenabled javascript for device-selector
Jochen Krapf (26):
Rework of plugin ADC (#319)
Added _P054_DMX512 (#322)
Added _P055_Chiming (#323)
Added _P056_SDS011-Dust (#324)
Added Plugin for Quadrature Encoder Interface (Rotary Encoder) (#335)
Added Plugin _P061_KeyPad (#340)
Added Plugin _P060_MCP3221 (#342)
Formula option for _P013_HCSR04 plugin issue #343 #313 (#344)
Fixed issues #308 #305 (#345)
Added Plugin _P062_MPR121_KeyPad (#346)
Fixed issue #348 (#349)
Added plugins for HT16K33 LED matrix driver and key pad scanner (#328)
Increase DEVICES_MAX for more testing and dev plugins (#353)
Write default CSS to SPIFFS on boot (#357)
Fixed DEVICES_MAX for testing and dev (#374)
Step back to style-based-css for speed up + pimp menu (#376)
Check plugin-array size on init - issue #119 (#389)
Added Plugin for MP3 module (#402)
Minor corrections and documentation (#404)
Added Plugin for Gesture Sensor APDS9960 (#409)
Added Plugin for Color Sensor VEML6040 (#412)
Added Plugin for HX711 Load Cell - Request #408 (#415)
Fixed multiline define bug on CRLF (#416)
Added Value Logger on SD Card (#429)
Plugin65 MP3 - volume updated in device menu - issue #424 (#438)
Plugin HX711 - Added Tare function (#419)
PieVo (1):
Update P053 (PMSx003) to support software serial and minor cleanup (#390)
SloMusti (3):
fixed deep sleep, such that it can be enabled from Rules (#375)
Implemented a better WiFI AP naming strategy. ESP_Easy has replaced the newdevice text as the default name and now the name is used as and AP SSID (#410)
added mDNS implementation (#418)
elucas2uy (1):
FIX Pass and Index on handle_controllers() (#331)
imthemichi (1):
Plugin_008-RFID extended with wiegand 34-bits and key-pad (#387)
krikk (6):
reverted change, this fix seems to have exactly opposite outcome than expected... with the fix applied i get errors, without is i get no errors... (#320)
changed the ina219 plugin so that is always sends 3 values, voltage, current, power... like a normal plugin should do... (#325)
delay option should be displayed even if the SendDataOption is false, because the delay option also controls the refresh rate of the oled display... fixes issue #336 (#339)
seconds were displayed without leading zero issue #337 (#338)
added local ip to sysinfo plugin, due to limitation of return type float, i had to split up the ip in its octets... fixes issue #228 (#341)
implemented a measurement type selection to retain backward compability to Domoticz... hope this works... (#351)
mvdbro (8):
Fix Domoticz helper plugin #330
Enlarge MQTT buffer for Domoticz MQTT controller
MQTT Controller enable/disable fix (#287)
Fix incorrect ADC GPIO display
Fix default controller settings (#360)
Added pin state buffer table page (mainly for debugging)
Update checkRAM function
Revert to default ESP Easy colorscheme
papperone (5):
Fixed Broken P038
p038
reverted some changes due to bug fixed in the "webserver.ino #348"
P038 - optimization
P010 plugin optimization (#403)
tedenda (2):
Renamed Prefix from P011 to C011
Missed one...
-----------------------------
Changes in release v2.0.0-dev10
-----------------------------
Release date: Mon May 29 22:53:54 CEST 2017
DatuX (1):
Update README.md
Jochen Krapf (1):
Rework of plugin ADC (#319)
krikk (1):
reverted change, this fix seems to have exactly opposite outcome than expected... with the fix applied i get errors, without is i get no errors... (#320)
-----------------------------
Changes in release v2.0.0-dev9
-----------------------------
Release date: Sun May 28 15:16:00 CEST 2017
Alex Schwantes (1):
Implemented use of addFormSelector methods to _P004_Dallas plugin. Changed the device select box to show the one wire address for each connected sensor instead of just a number. Added a blank option to the device address select box so that in the event that multiple devices are present and the configured device is not currently available, the select box will be blank instead of selecting a different device.
Bartlomiej Zimon (5):
- Misc: typo
Custom Controller Settings - add controller index
Push ProtocolIndex and ControllerIndex into CPLUGIN_WEBFORM_SAVE/LOAD
Add WifiSSID2,WifiKey2 commands
Add backup Wifi network to Settings command
Blair Thompson (1):
Added Par4 and Par5 Variables (#248)
Daniel Tedenljung (5):
Updated wrong plugin number. (#269)
P052: More descriptive log messages (#283)
GUI touchup on Tools (#286)
addSubmitButton function added (#289)
New look on Tools page (#296)
DatuX (5):
Update README.md
Update issue_template.md
Update CONTRIBUTING.md
Update README.md
Update README.md
Edwin Eefting (17):
cleaned up messagedelay: use the same function everywhere. and do serial processing as well during the messagedelay
fixed issue #253 (memory leaks/crashes)
more details in memory analyser. run memory analyser via Travis
cosmetic buildlog fix
publish MQTT Connected message
timer boundschecker was off by one. fixed memanalyser total
input box fix on setting pages
comments. checkudp only in backgroundtasks()
reboot and wifidisconnect should be handled by /
bugfix in rtc checksum
nicer sleep messages
fixed a few out of bounds bugs in Misc.ino _P023_OLED.ino _P035_IRTX.ino _P037_MQTTImport.ino with cppcheck. also added cppcheck to travis to prevent such cases in the future
fixing cpp check
fixing cpp check
fixing cpp check
fixing cpp check
also distribute ESP8285 binaries
JK (5):
added functions addCheckBox and addNumericBox
added checkbox for status LED inversed
fine tuning of status LED and pimp hardware web site
solved my commit mismatch
Fixed #196 and rework of IDX display
Jochen Krapf (11):
Added addForm*-functions for easy web-interface and pimp GUI (#259)
Added function addFormSelector (#270)
Preliminary final draft of bugfix #264 (#271)
Replaced HTML code with addFormSelector() in all plugins (#278)
Fixed readUserVarFromRTC() #265 (#280)
Limits to NumericBox and a bit of security to PasswordBox (#281)
Added HTML templates for customization (#290)
Fixed rules bug #297 (#299)
Pimp device-GUI and optimized HTML (#306)
Fixed some minor HTML syntax bugs (#310)
Rework of plugin ADS1115 (#315)
PieVo (1):
Plantower (#300)
beic (1):
Some little description corrections (#297)
krikk (13):
http advanced controller, correct passing of hostname (#250)
i2c Temperatur & Humidity Sensor Am2320 (#251)
use the new addCheckBox function and better display of device config page
another fix to http advanced...
replaced static html code with the new addForm* Functions
bug fix wrong return type + form function fixes (#266)
addFormNumeric with min and max & More Form-Function replacements (#272)
make the Settings - Save. Filename more descriptive... (#273)
addHelpButton Function and a new Help Button for the Rules and Hardware Page (#282)
DHT plugin fix 'NaN' issue (#285)
i don't like hidden features, added a json button to the tools menu, next to the advanced button (#292)
do a dns lookup on every request, solves issue #261 (#302)
AM2320: negative temperature fix... (#312)
tedenda (1):
Moving plugin from Playground into main repo. (#262)
-----------------------------
Changes in release v2.0.0-dev8
-----------------------------
+59
View File
@@ -0,0 +1,59 @@
#include "AM2320.h"
#include <Wire.h>
//
// AM2321 Temperature & Humidity Sensor library for Arduino
// Сделана Тимофеевым Е.Н. из AM2320-master
unsigned int CRC16(byte *ptr, byte length)
{
unsigned int crc = 0xFFFF;
uint8_t s = 0x00;
while(length--) {
crc ^= *ptr++;
for(s = 0; s < 8; s++) {
if((crc & 0x01) != 0) {
crc >>= 1;
crc ^= 0xA001;
} else crc >>= 1;
}
}
return crc;
}
AM2320::AM2320()
{
}
int AM2320::Read()
{
byte buf[8];
for(int s = 0; s < 8; s++) buf[s] = 0x00;
Wire.beginTransmission(AM2320_address);
Wire.endTransmission();
// запрос 4 байт (температуры и влажности)
Wire.beginTransmission(AM2320_address);
Wire.write(0x03);// запрос
Wire.write(0x00); // с 0-го адреса
Wire.write(0x04); // 4 байта
if (Wire.endTransmission(1) != 0) return 1;
delayMicroseconds(1600); //>1.5ms
// считываем результаты запроса
Wire.requestFrom(AM2320_address, 0x08);
for (int i = 0; i < 0x08; i++) buf[i] = Wire.read();
// CRC check
unsigned int Rcrc = buf[7] << 8;
Rcrc += buf[6];
if (Rcrc == CRC16(buf, 6)) {
unsigned int temperature = ((buf[4] & 0x7F) << 8) + buf[5];
t = temperature / 10.0;
t = ((buf[4] & 0x80) >> 7) == 1 ? t * (-1) : t;
unsigned int humidity = (buf[2] << 8) + buf[3];
h = humidity / 10.0;
return 0;
}
return 2;
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef AM2320_H
#define AM2320_H
#include <Arduino.h>
#define AM2320_address (0xB8 >> 1)
class AM2320
{
public:
AM2320();
float t;
float h;
int Read(void);
};
#endif
@@ -0,0 +1,29 @@
#include <Wire.h>
#include <AM2320.h>
AM2320 th;
void setup() {
Serial.begin(9600);
Wire.begin();
}
void loop() {
switch(th.Read()) {
case 2:
Serial.println("CRC failed");
break;
case 1:
Serial.println("Sensor offline");
break;
case 0:
Serial.print("humidity: ");
Serial.print(th.h);
Serial.print("%, temperature: ");
Serial.print(th.t);
Serial.println("*C");
break;
}
delay(200);
}
+4
View File
@@ -0,0 +1,4 @@
AM2320 KEYWORD1
getTemperature KEYWORD2
getHumidity KEYWORD2
CRCCheck KEYWORD2
+132
View File
@@ -0,0 +1,132 @@
/***************************************************
This is a library for the MPR121 I2C 12-chan Capacitive Sensor
Designed specifically to work with the MPR121 sensor from Adafruit
----> https://www.adafruit.com/products/1982
These sensors use I2C to communicate, 2+ pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_MPR121.h"
Adafruit_MPR121::Adafruit_MPR121() {
}
boolean Adafruit_MPR121::begin(uint8_t i2caddr) {
Wire.begin();
_i2caddr = i2caddr;
// soft reset
writeRegister(MPR121_SOFTRESET, 0x63);
delay(1);
for (uint8_t i=0; i<0x7F; i++) {
// Serial.print("$"); Serial.print(i, HEX);
// Serial.print(": 0x"); Serial.println(readRegister8(i));
}
writeRegister(MPR121_ECR, 0x0);
uint8_t c = readRegister8(MPR121_CONFIG2);
if (c != 0x24) return false;
setThreshholds(12, 6);
writeRegister(MPR121_MHDR, 0x01);
writeRegister(MPR121_NHDR, 0x01);
writeRegister(MPR121_NCLR, 0x0E);
writeRegister(MPR121_FDLR, 0x00);
writeRegister(MPR121_MHDF, 0x01);
writeRegister(MPR121_NHDF, 0x05);
writeRegister(MPR121_NCLF, 0x01);
writeRegister(MPR121_FDLF, 0x00);
writeRegister(MPR121_NHDT, 0x00);
writeRegister(MPR121_NCLT, 0x00);
writeRegister(MPR121_FDLT, 0x00);
writeRegister(MPR121_DEBOUNCE, 0);
writeRegister(MPR121_CONFIG1, 0x10); // default, 16uA charge current
writeRegister(MPR121_CONFIG2, 0x20); // 0.5uS encoding, 1ms period
// writeRegister(MPR121_AUTOCONFIG0, 0x8F);
// writeRegister(MPR121_UPLIMIT, 150);
// writeRegister(MPR121_TARGETLIMIT, 100); // should be ~400 (100 shifted)
// writeRegister(MPR121_LOWLIMIT, 50);
// enable all electrodes
writeRegister(MPR121_ECR, 0x8F); // start with first 5 bits of baseline tracking
return true;
}
void Adafruit_MPR121::setThreshholds(uint8_t touch, uint8_t release) {
setThresholds(touch, release);
}
void Adafruit_MPR121::setThresholds(uint8_t touch, uint8_t release) {
for (uint8_t i=0; i<12; i++) {
writeRegister(MPR121_TOUCHTH_0 + 2*i, touch);
writeRegister(MPR121_RELEASETH_0 + 2*i, release);
}
}
uint16_t Adafruit_MPR121::filteredData(uint8_t t) {
if (t > 12) return 0;
return readRegister16(MPR121_FILTDATA_0L + t*2);
}
uint16_t Adafruit_MPR121::baselineData(uint8_t t) {
if (t > 12) return 0;
uint16_t bl = readRegister8(MPR121_BASELINE_0 + t);
return (bl << 2);
}
uint16_t Adafruit_MPR121::touched(void) {
uint16_t t = readRegister16(MPR121_TOUCHSTATUS_L);
return t & 0x0FFF;
}
/*********************************************************************/
uint8_t Adafruit_MPR121::readRegister8(uint8_t reg) {
Wire.beginTransmission(_i2caddr);
Wire.write(reg);
Wire.endTransmission(false);
while (Wire.requestFrom(_i2caddr, 1) != 1);
return ( Wire.read());
}
uint16_t Adafruit_MPR121::readRegister16(uint8_t reg) {
Wire.beginTransmission(_i2caddr);
Wire.write(reg);
Wire.endTransmission(false);
while (Wire.requestFrom(_i2caddr, 2) != 2);
uint16_t v = Wire.read();
v |= ((uint16_t) Wire.read()) << 8;
return v;
}
/**************************************************************************/
/*!
@brief Writes 8-bits to the specified destination register
*/
/**************************************************************************/
void Adafruit_MPR121::writeRegister(uint8_t reg, uint8_t value) {
Wire.beginTransmission(_i2caddr);
Wire.write((uint8_t)reg);
Wire.write((uint8_t)(value));
Wire.endTransmission();
}
+94
View File
@@ -0,0 +1,94 @@
/***************************************************
This is a library for the MPR121 12-Channel Capacitive Sensor
Designed specifically to work with the MPR121 breakout from Adafruit
----> https://www.adafruit.com/products/1982
These sensors use I2C to communicate, 2+ pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#ifndef ADAFRUIT_MPR121_H
#define ADAFRUIT_MPR121_H
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <Wire.h>
// The default I2C address
#define MPR121_I2CADDR_DEFAULT 0x5A
#define MPR121_TOUCHSTATUS_L 0x00
#define MPR121_TOUCHSTATUS_H 0x01
#define MPR121_FILTDATA_0L 0x04
#define MPR121_FILTDATA_0H 0x05
#define MPR121_BASELINE_0 0x1E
#define MPR121_MHDR 0x2B
#define MPR121_NHDR 0x2C
#define MPR121_NCLR 0x2D
#define MPR121_FDLR 0x2E
#define MPR121_MHDF 0x2F
#define MPR121_NHDF 0x30
#define MPR121_NCLF 0x31
#define MPR121_FDLF 0x32
#define MPR121_NHDT 0x33
#define MPR121_NCLT 0x34
#define MPR121_FDLT 0x35
#define MPR121_TOUCHTH_0 0x41
#define MPR121_RELEASETH_0 0x42
#define MPR121_DEBOUNCE 0x5B
#define MPR121_CONFIG1 0x5C
#define MPR121_CONFIG2 0x5D
#define MPR121_CHARGECURR_0 0x5F
#define MPR121_CHARGETIME_1 0x6C
#define MPR121_ECR 0x5E
#define MPR121_AUTOCONFIG0 0x7B
#define MPR121_AUTOCONFIG1 0x7C
#define MPR121_UPLIMIT 0x7D
#define MPR121_LOWLIMIT 0x7E
#define MPR121_TARGETLIMIT 0x7F
#define MPR121_GPIODIR 0x76
#define MPR121_GPIOEN 0x77
#define MPR121_GPIOSET 0x78
#define MPR121_GPIOCLR 0x79
#define MPR121_GPIOTOGGLE 0x7A
#define MPR121_SOFTRESET 0x80
//.. thru to 0x1C/0x1D
class Adafruit_MPR121 {
public:
// Hardware I2C
Adafruit_MPR121(void);
boolean begin(uint8_t i2caddr = MPR121_I2CADDR_DEFAULT);
uint16_t filteredData(uint8_t t);
uint16_t baselineData(uint8_t t);
uint8_t readRegister8(uint8_t reg);
uint16_t readRegister16(uint8_t reg);
void writeRegister(uint8_t reg, uint8_t value);
uint16_t touched(void);
// Add deprecated attribute so that the compiler shows a warning
__attribute__((deprecated)) void setThreshholds(uint8_t touch, uint8_t release);
void setThresholds(uint8_t touch, uint8_t release);
private:
int8_t _i2caddr;
};
#endif // ADAFRUIT_MPR121_H
+32
View File
@@ -0,0 +1,32 @@
# Adafruit_MPR121_Library
<!-- START COMPATIBILITY TABLE -->
## Compatibility
MCU | Tested Works | Doesn't Work | Not Tested | Notes
------------------ | :----------: | :----------: | :---------: | -----
Atmega328 @ 16MHz | X | | |
Atmega328 @ 12MHz | X | | |
Atmega32u4 @ 16MHz | X | | |
Atmega32u4 @ 8MHz | X | | |
ESP8266 | | X | |
Atmega2560 @ 16MHz | X | | |
ATSAM3X8E | | X | |
ATSAM21D | X | | |
ATtiny85 @ 16MHz | | | X |
ATtiny85 @ 8MHz | | | X |
Intel Curie @ 32MHz | | | X |
STM32F2 | | | X |
* ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini
* ATmega328 @ 12MHz : Adafruit Pro Trinket 3V
* ATmega32u4 @ 16MHz : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0
* ATmega32u4 @ 8MHz : Adafruit Flora, Bluefruit Micro
* ESP8266 : Adafruit Huzzah
* ATmega2560 @ 16MHz : Arduino Mega
* ATSAM3X8E : Arduino Due
* ATSAM21D : Arduino Zero, M0 Pro
* ATtiny85 @ 16MHz : Adafruit Trinket 5V
* ATtiny85 @ 8MHz : Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V
<!-- END COMPATIBILITY TABLE -->
+25
View File
@@ -0,0 +1,25 @@
This is a library for the MPR121 12-channel Capacitive touch sensor
Designed specifically to work with the MPR121 Breakout in the Adafruit shop
----> https://www.adafruit.com/products/1982
These sensors use I2C communicate, at least 2 pins are required
to interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
Check out the links above for our tutorials and wiring diagrams
To download. click the ZIP button, and rename the uncompressed folder Adafruit_MPR121
Check that the Adafruit_MPR121 folder contains Adafruit_MPR121.cpp and Adafruit_MPR121.h
Place the Adafruit_MPR121 library folder your arduinosketchfolder/libraries/ folder.
You may need to create the libraries subfolder if its your first library. Restart the IDE.
We also have a great tutorial on Arduino library installation at:
http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use
@@ -0,0 +1,83 @@
/*********************************************************
This is a library for the MPR121 12-channel Capacitive touch sensor
Designed specifically to work with the MPR121 Breakout in the Adafruit shop
----> https://www.adafruit.com/products/
These sensors use I2C communicate, at least 2 pins are required
to interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
**********************************************************/
#include <Wire.h>
#include "Adafruit_MPR121.h"
// You can have up to 4 on one i2c bus but one is enough for testing!
Adafruit_MPR121 cap = Adafruit_MPR121();
// Keeps track of the last pins touched
// so we know when buttons are 'released'
uint16_t lasttouched = 0;
uint16_t currtouched = 0;
void setup() {
Serial.begin(9600);
while (!Serial) { // needed to keep leonardo/micro from starting too fast!
delay(10);
}
Serial.println("Adafruit MPR121 Capacitive Touch sensor test");
// Default address is 0x5A, if tied to 3.3V its 0x5B
// If tied to SDA its 0x5C and if SCL then 0x5D
if (!cap.begin(0x5A)) {
Serial.println("MPR121 not found, check wiring?");
while (1);
}
Serial.println("MPR121 found!");
}
void loop() {
// Get the currently touched pads
currtouched = cap.touched();
for (uint8_t i=0; i<12; i++) {
// it if *is* touched and *wasnt* touched before, alert!
if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
Serial.print(i); Serial.println(" touched");
}
// if it *was* touched and now *isnt*, alert!
if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
Serial.print(i); Serial.println(" released");
}
}
// reset our state
lasttouched = currtouched;
// comment out this line for detailed data from the sensor!
return;
// debugging info, what
Serial.print("\t\t\t\t\t\t\t\t\t\t\t\t\t 0x"); Serial.println(cap.touched(), HEX);
Serial.print("Filt: ");
for (uint8_t i=0; i<12; i++) {
Serial.print(cap.filteredData(i)); Serial.print("\t");
}
Serial.println();
Serial.print("Base: ");
for (uint8_t i=0; i<12; i++) {
Serial.print(cap.baselineData(i)); Serial.print("\t");
}
Serial.println();
// put a delay so it isn't overwhelming
delay(100);
}
+6
View File
@@ -0,0 +1,6 @@
Adafruit_MPR121 KEYWORD1
begin KEYWORD2
filteredData KEYWORD2
baselineData KEYWORD2
touched KEYWORD2
setThresholds KEYWORD2
+9
View File
@@ -0,0 +1,9 @@
name=Adafruit MPR121
version=1.0.0
author=Adafruit <info@adafruit.com>
maintainer=Adafruit <info@adafruit.com>
sentence=Arduino library for the MPR121-based capacitive sensors in the Adafruit shop.
paragraph=Designed specifically to work with the MPR121 Breakout in the Adafruit shop.
category=Sensors
url=https://github.com/adafruit/Adafruit_MPR121
architectures=*
+174
View File
@@ -0,0 +1,174 @@
#include "HT16K33.h"
#include <Wire.h>
CHT16K33::CHT16K33(void)
{
};
void CHT16K33::Init(uint8_t addr)
{
_addr = addr;
// System Setup Register
Wire.beginTransmission(_addr);
Wire.write(0x21); // oscillator on
Wire.endTransmission();
// Display Setup Register
Wire.beginTransmission(_addr);
Wire.write(0x81); // blink off; display on
Wire.endTransmission();
SetBrightness(15);
ClearRowBuffer();
TransmitRowBuffer();
};
void CHT16K33::SetBrightness(uint8_t b)
{
if (b > 15)
b = 15;
// Digital Dimming Data Input
Wire.beginTransmission(_addr);
Wire.write(0xE0 | b); // brightness
Wire.endTransmission();
};
void CHT16K33::TransmitRowBuffer(void)
{
// Display Memory
Wire.beginTransmission(_addr);
Wire.write(0); // start data at address 0
for (byte i=0; i<8; i++)
{
Wire.write(_rowBuffer[i] & 0xFF);
Wire.write(_rowBuffer[i] >> 8);
}
Wire.endTransmission();
};
void CHT16K33::ClearRowBuffer(void)
{
for (byte i=0; i<8; i++)
_rowBuffer[i] = 0;
};
void CHT16K33::SetRow(uint8_t com, uint16_t data)
{
if (com < 8)
_rowBuffer[com] = data;
};
uint16_t CHT16K33::GetRow(uint8_t com)
{
if (com < 8)
return _rowBuffer[com];
else
return 0;
};
void CHT16K33::SetDigit(uint8_t com, uint8_t c)
{
uint16_t value = 0;
if (c <= 0xF)
value = _digits[c];
switch (c)
{
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
value = c + 10 - 'A';
value = _digits[value & 0xF];
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
value = c - '0';
value = _digits[value & 0xF];
break;
case ' ':
value = 0;
break;
case ':':
value = 0x02; //special for China 4 x 7-seg big display
break;
case '-':
value = 0x40;
break;
}
SetRow(com, value);
}
uint8_t CHT16K33::ReadKeys(void)
{
// Display Memory
Wire.beginTransmission(_addr);
Wire.write(0x40); // start data at address 0x40
Wire.endTransmission();
Wire.requestFrom(_addr, (uint8_t)6);
if (Wire.available() == 6)
{
for (byte i=0; i<3; i++)
{
_keyBuffer[i] = Wire.read() | (Wire.read() << 8);
}
Wire.endTransmission();
}
for (byte i=0; i<3; i++)
{
byte mask = 1;
for (byte k=0; k<12; k++)
{
if (_keyBuffer[i] & mask)
{
_keydown = 16*(i+1) + (k+1);
return _keydown;
}
mask <<= 1;
}
}
_keydown = 0;
return _keydown;
};
const uint8_t CHT16K33::_digits[16] =
{
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F, // 9
0x77, // A
0x7C, // B
0x39, // C
0x5E, // D
0x79, // E
0x71, // F
};
+34
View File
@@ -0,0 +1,34 @@
#ifndef CHT16K33_h
#define CHT16K33_h
#include <Arduino.h>
class CHT16K33 {
public:
CHT16K33(void);
void Init(uint8_t addr);
// LED buffer
void ClearRowBuffer(void);
void SetRow(uint8_t com, uint16_t data);
uint16_t GetRow(uint8_t com);
void SetDigit(uint8_t com, uint8_t c);
// LED output and control
void SetBrightness(uint8_t b);
void TransmitRowBuffer(void);
//KeyPad Scan
uint8_t ReadKeys(void);
protected:
uint8_t _addr;
uint16_t _rowBuffer[8];
uint16_t _keyBuffer[3];
byte _keydown;
static const uint8_t _digits[16];
};
#endif
+9
View File
@@ -0,0 +1,9 @@
name=CHT16K33 LED Matrix Library
version=0.0.1
author=Jochen Krapf
maintainer=Jochen Krapf <jk@nerd2nerd.org>
sentence=CHT16K33 16x8 LED and 13x3 KeyPad Matrix Library
paragraph=CHT16K33 16x8 LED and 13x3 KeyPad Matrix Library
category=LED
url=https://github.com/???
architectures=esp8266,avr
+5 -4
View File
@@ -1,13 +1,14 @@
language: c
env:
- BD=esp8266:esp8266:nodemcuv2:CpuFrequency=80,FlashSize=4M3M
- BD=esp8266:esp8266:d1_mini:CpuFrequency=80,FlashSize=4M3M
before_install:
- "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16"
- sleep 3
- export DISPLAY=:1.0
- wget http://downloads.arduino.cc/arduino-1.8.1-linux64.tar.xz
- tar xf arduino-1.8.1-linux64.tar.xz
- sudo mv arduino-1.8.1 /usr/local/share/arduino
- wget http://downloads.arduino.cc/arduino-1.8.2-linux64.tar.xz
- tar xf arduino-1.8.2-linux64.tar.xz
- sudo mv arduino-1.8.2 /usr/local/share/arduino
- sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino
install:
- ln -s $PWD /usr/local/share/arduino/libraries/
@@ -25,7 +26,7 @@ script:
- arduino --verify --board $BD $PWD/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino
- arduino --verify --board $BD $PWD/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino
- arduino --verify --board $BD $PWD/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino
- arduino --verify --board $BD $PWD/examples/TurnOnKelvinatorAC/TurnOnMitsubishiAC.ino
- arduino --verify --board $BD $PWD/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino
notifications:
email:
+18 -18
View File
@@ -9,17 +9,17 @@ IRDaikinESP::IRDaikinESP(int pin) : _irsend(pin)
{
}
void IRDaikinESP::begin()
void ICACHE_FLASH_ATTR IRDaikinESP::begin()
{
_irsend.begin();
}
void IRDaikinESP::send()
void ICACHE_FLASH_ATTR IRDaikinESP::send()
{
_irsend.sendDaikin(daikin);
}
void IRDaikinESP::checksum()
void ICACHE_FLASH_ATTR IRDaikinESP::checksum()
{
uint8_t sum = 0;
uint8_t i;
@@ -36,39 +36,39 @@ void IRDaikinESP::checksum()
daikin[26] = sum &0xFF;
}
void IRDaikinESP::on()
void ICACHE_FLASH_ATTR IRDaikinESP::on()
{
//state = ON;
daikin[13] |= 0x01;
checksum();
}
void IRDaikinESP::off()
void ICACHE_FLASH_ATTR IRDaikinESP::off()
{
//state = OFF;
daikin[13] &= 0xFE;
checksum();
}
uint8_t IRDaikinESP::getPower()
uint8_t ICACHE_FLASH_ATTR IRDaikinESP::getPower()
{
return (daikin[13])&0x01;
}
// DAIKIN_SILENT or DAIKIN_POWERFUL
void IRDaikinESP::setAux(uint8_t aux)
void ICACHE_FLASH_ATTR IRDaikinESP::setAux(uint8_t aux)
{
daikin[21] = aux;
checksum();
}
uint8_t IRDaikinESP::getAux(){
uint8_t ICACHE_FLASH_ATTR IRDaikinESP::getAux(){
return daikin[21];
}
// Set the temp in deg C
void IRDaikinESP::setTemp(uint8_t temp)
void ICACHE_FLASH_ATTR IRDaikinESP::setTemp(uint8_t temp)
{
if (temp < 18)
temp = 18;
@@ -78,13 +78,13 @@ void IRDaikinESP::setTemp(uint8_t temp)
checksum();
}
uint8_t IRDaikinESP::getTemp()
uint8_t ICACHE_FLASH_ATTR IRDaikinESP::getTemp()
{
return (daikin[14])/2;
}
// Set the speed of the fan, 0-5, 0 is auto, 1-5 is the speed
void IRDaikinESP::setFan(uint8_t fan)
void ICACHE_FLASH_ATTR IRDaikinESP::setFan(uint8_t fan)
{
// Set the fan speed bits, leave low 4 bits alone
uint8_t fanset;
@@ -97,7 +97,7 @@ void IRDaikinESP::setFan(uint8_t fan)
checksum();
}
uint8_t IRDaikinESP::getFan()
uint8_t ICACHE_FLASH_ATTR IRDaikinESP::getFan()
{
uint8_t fan = daikin[16] >> 4;
fan = fan - 2;
@@ -106,7 +106,7 @@ uint8_t IRDaikinESP::getFan()
return fan;
}
uint8_t IRDaikinESP::getMode()
uint8_t ICACHE_FLASH_ATTR IRDaikinESP::getMode()
{/*
DAIKIN_COOL
DAIKIN_HEAT
@@ -117,13 +117,13 @@ uint8_t IRDaikinESP::getMode()
return (daikin[13])>>4;
}
void IRDaikinESP::setMode(uint8_t mode)
void ICACHE_FLASH_ATTR IRDaikinESP::setMode(uint8_t mode)
{
daikin[13]=mode<<4 | getPower();
checksum();
}
void IRDaikinESP::setSwingVertical(uint8_t swing)
void ICACHE_FLASH_ATTR IRDaikinESP::setSwingVertical(uint8_t swing)
{
if (swing)
daikin[16] = daikin[16] | 0x0F;
@@ -132,12 +132,12 @@ void IRDaikinESP::setSwingVertical(uint8_t swing)
checksum();
}
uint8_t IRDaikinESP::getSwingVertical()
uint8_t ICACHE_FLASH_ATTR IRDaikinESP::getSwingVertical()
{
return (daikin[16])&0x01;
}
void IRDaikinESP::setSwingHorizontal(uint8_t swing)
void ICACHE_FLASH_ATTR IRDaikinESP::setSwingHorizontal(uint8_t swing)
{
if (swing)
daikin[17] = daikin[17] | 0x0F;
@@ -146,7 +146,7 @@ void IRDaikinESP::setSwingHorizontal(uint8_t swing)
checksum();
}
uint8_t IRDaikinESP::getSwingHorizontal()
uint8_t ICACHE_FLASH_ATTR IRDaikinESP::getSwingHorizontal()
{
return (daikin[17])&0x01;
}
+30 -30
View File
@@ -20,36 +20,36 @@ IRKelvinatorAC::IRKelvinatorAC(int pin) : _irsend(pin) {
stateReset();
}
void IRKelvinatorAC::stateReset() {
void ICACHE_FLASH_ATTR IRKelvinatorAC::stateReset() {
for (uint8_t i = 0; i < KELVINATOR_STATE_LENGTH; i++)
remote_state[i] = 0x0;
remote_state[3] = 0x50;
remote_state[11] = 0x70;
}
void IRKelvinatorAC::begin() {
void ICACHE_FLASH_ATTR IRKelvinatorAC::begin() {
_irsend.begin();
}
void IRKelvinatorAC::fixup() {
void ICACHE_FLASH_ATTR IRKelvinatorAC::fixup() {
// X-Fan mode is only valid in COOL or DRY modes.
if (getMode() != KELVINATOR_COOL && getMode() != KELVINATOR_DRY)
setXFan(false);
checksum(); // Calculate the checksums
}
void IRKelvinatorAC::send() {
void ICACHE_FLASH_ATTR IRKelvinatorAC::send() {
fixup(); // Ensure correct settings before sending.
_irsend.sendKelvinator(remote_state);
}
uint8_t* IRKelvinatorAC::getRaw() {
uint8_t* ICACHE_FLASH_ATTR IRKelvinatorAC::getRaw() {
fixup(); // Ensure correct settings before sending.
return remote_state;
}
// Many Bothans died to bring us this information.
void IRKelvinatorAC::checksum() {
void ICACHE_FLASH_ATTR IRKelvinatorAC::checksum() {
// For each command + options block.
for (uint8_t offset = 0; offset < KELVINATOR_STATE_LENGTH; offset += 8) {
uint8_t sum = KELVINATOR_CHECKSUM_START;
@@ -68,31 +68,31 @@ void IRKelvinatorAC::checksum() {
}
}
void IRKelvinatorAC::on() {
void ICACHE_FLASH_ATTR IRKelvinatorAC::on() {
//state = ON;
remote_state[0] |= KELVINATOR_POWER;
remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk.
}
void IRKelvinatorAC::off() {
void ICACHE_FLASH_ATTR IRKelvinatorAC::off() {
//state = OFF;
remote_state[0] &= ~KELVINATOR_POWER;
remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk.
}
void IRKelvinatorAC::setPower(bool state) {
void ICACHE_FLASH_ATTR IRKelvinatorAC::setPower(bool state) {
if (state)
on();
else
off();
}
bool IRKelvinatorAC::getPower() {
bool ICACHE_FLASH_ATTR IRKelvinatorAC::getPower() {
return ((remote_state[0] & KELVINATOR_POWER) != 0);
}
// Set the temp. in deg C
void IRKelvinatorAC::setTemp(uint8_t temp) {
void ICACHE_FLASH_ATTR IRKelvinatorAC::setTemp(uint8_t temp) {
temp = max(KELVINATOR_MIN_TEMP, temp);
temp = min(KELVINATOR_MAX_TEMP, temp);
remote_state[1] = (remote_state[1] & 0xF0U) | (temp - KELVINATOR_MIN_TEMP);
@@ -100,12 +100,12 @@ void IRKelvinatorAC::setTemp(uint8_t temp) {
}
// Return the set temp. in deg C
uint8_t IRKelvinatorAC::getTemp() {
uint8_t ICACHE_FLASH_ATTR IRKelvinatorAC::getTemp() {
return ((remote_state[1] & 0xFU) + KELVINATOR_MIN_TEMP);
}
// Set the speed of the fan, 0-5, 0 is auto, 1-5 is the speed
void IRKelvinatorAC::setFan(uint8_t fan) {
void ICACHE_FLASH_ATTR IRKelvinatorAC::setFan(uint8_t fan) {
fan = min(KELVINATOR_FAN_MAX, fan); // Bounds check
// Only change things if we need to.
@@ -122,11 +122,11 @@ void IRKelvinatorAC::setFan(uint8_t fan) {
}
}
uint8_t IRKelvinatorAC::getFan() {
uint8_t ICACHE_FLASH_ATTR IRKelvinatorAC::getFan() {
return ((remote_state[14] & ~KELVINATOR_FAN_MASK) >> KELVINATOR_FAN_OFFSET);
}
uint8_t IRKelvinatorAC::getMode() {
uint8_t ICACHE_FLASH_ATTR IRKelvinatorAC::getMode() {
/*
KELVINATOR_AUTO
KELVINATOR_COOL
@@ -137,7 +137,7 @@ uint8_t IRKelvinatorAC::getMode() {
return (remote_state[0] & ~KELVINATOR_MODE_MASK);
}
void IRKelvinatorAC::setMode(uint8_t mode) {
void ICACHE_FLASH_ATTR IRKelvinatorAC::setMode(uint8_t mode) {
// If we get an unexpected mode, default to AUTO.
if (mode > KELVINATOR_HEAT) mode = KELVINATOR_AUTO;
remote_state[0] = (remote_state[0] & KELVINATOR_MODE_MASK) | mode;
@@ -147,7 +147,7 @@ void IRKelvinatorAC::setMode(uint8_t mode) {
setTemp(KELVINATOR_AUTO_TEMP);
}
void IRKelvinatorAC::setSwingVertical(bool state) {
void ICACHE_FLASH_ATTR IRKelvinatorAC::setSwingVertical(bool state) {
if (state) {
remote_state[0] |= KELVINATOR_VENT_SWING;
remote_state[4] |= KELVINATOR_VENT_SWING_V;
@@ -160,11 +160,11 @@ void IRKelvinatorAC::setSwingVertical(bool state) {
remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk.
}
bool IRKelvinatorAC::getSwingVertical() {
bool ICACHE_FLASH_ATTR IRKelvinatorAC::getSwingVertical() {
return ((remote_state[4] & KELVINATOR_VENT_SWING_V) != 0);
}
void IRKelvinatorAC::setSwingHorizontal(bool state) {
void ICACHE_FLASH_ATTR IRKelvinatorAC::setSwingHorizontal(bool state) {
if (state) {
remote_state[0] |= KELVINATOR_VENT_SWING;
remote_state[4] |= KELVINATOR_VENT_SWING_H;
@@ -177,57 +177,57 @@ void IRKelvinatorAC::setSwingHorizontal(bool state) {
remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk.
}
bool IRKelvinatorAC::getSwingHorizontal() {
bool ICACHE_FLASH_ATTR IRKelvinatorAC::getSwingHorizontal() {
return ((remote_state[4] & KELVINATOR_VENT_SWING_H) != 0);
}
void IRKelvinatorAC::setQuiet(bool state) {
void ICACHE_FLASH_ATTR IRKelvinatorAC::setQuiet(bool state) {
remote_state[12] &= ~KELVINATOR_QUIET;
remote_state[12] |= (state << KELVINATOR_QUIET_OFFSET);
}
bool IRKelvinatorAC::getQuiet() {
bool ICACHE_FLASH_ATTR IRKelvinatorAC::getQuiet() {
return ((remote_state[12] & KELVINATOR_QUIET) != 0);
}
void IRKelvinatorAC::setIonFilter(bool state) {
void ICACHE_FLASH_ATTR IRKelvinatorAC::setIonFilter(bool state) {
remote_state[2] &= ~KELVINATOR_ION_FILTER;
remote_state[2] |= (state << KELVINATOR_ION_FILTER_OFFSET);
remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk.
}
bool IRKelvinatorAC::getIonFilter() {
bool ICACHE_FLASH_ATTR IRKelvinatorAC::getIonFilter() {
return ((remote_state[2] & KELVINATOR_ION_FILTER) != 0);
}
void IRKelvinatorAC::setLight(bool state) {
void ICACHE_FLASH_ATTR IRKelvinatorAC::setLight(bool state) {
remote_state[2] &= ~KELVINATOR_LIGHT;
remote_state[2] |= (state << KELVINATOR_LIGHT_OFFSET);
remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk.
}
bool IRKelvinatorAC::getLight() {
bool ICACHE_FLASH_ATTR IRKelvinatorAC::getLight() {
return ((remote_state[2] & KELVINATOR_LIGHT) != 0);
}
// Note: XFan mode is only valid in Cool or Dry mode.
void IRKelvinatorAC::setXFan(bool state) {
void ICACHE_FLASH_ATTR IRKelvinatorAC::setXFan(bool state) {
remote_state[2] &= ~KELVINATOR_XFAN;
remote_state[2] |= (state << KELVINATOR_XFAN_OFFSET);
remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk.
}
bool IRKelvinatorAC::getXFan() {
bool ICACHE_FLASH_ATTR IRKelvinatorAC::getXFan() {
return ((remote_state[2] & KELVINATOR_XFAN) != 0);
}
// Note: Turbo mode is turned off if the fan speed is changed.
void IRKelvinatorAC::setTurbo(bool state) {
void ICACHE_FLASH_ATTR IRKelvinatorAC::setTurbo(bool state) {
remote_state[2] &= ~KELVINATOR_TURBO;
remote_state[2] |= (state << KELVINATOR_TURBO_OFFSET);
remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk.
}
bool IRKelvinatorAC::getTurbo() {
bool ICACHE_FLASH_ATTR IRKelvinatorAC::getTurbo() {
return ((remote_state[2] & KELVINATOR_TURBO) != 0);
}
+17 -17
View File
@@ -17,31 +17,31 @@ IRMitsubishiAC::IRMitsubishiAC(int pin) : _irsend(pin) {
}
// Reset the state of the remote to a known good state/sequence.
void IRMitsubishiAC::stateReset() {
void ICACHE_FLASH_ATTR IRMitsubishiAC::stateReset() {
for (uint8_t i = 0; i < MITSUBISHI_AC_STATE_LENGTH; i++)
remote_state[i] = known_good_state[i];
checksum(); // Calculate the checksum
}
// Configure the pin for output.
void IRMitsubishiAC::begin() {
void ICACHE_FLASH_ATTR IRMitsubishiAC::begin() {
_irsend.begin();
}
// Send the current desired state to the IR LED.
void IRMitsubishiAC::send() {
void ICACHE_FLASH_ATTR IRMitsubishiAC::send() {
checksum(); // Ensure correct checksum before sending.
_irsend.sendMitsubishiAC(remote_state);
}
// Return a pointer to the internal state date of the remote.
uint8_t* IRMitsubishiAC::getRaw() {
uint8_t* ICACHE_FLASH_ATTR IRMitsubishiAC::getRaw() {
checksum();
return remote_state;
}
// Calculate the checksum for the current internal state of the remote.
void IRMitsubishiAC::checksum() {
void ICACHE_FLASH_ATTR IRMitsubishiAC::checksum() {
uint8_t sum = 0;
// Checksum is simple addition of all previous bytes stored
// as a 8 bit value.
@@ -51,19 +51,19 @@ void IRMitsubishiAC::checksum() {
}
// Set the requested power state of the A/C to off.
void IRMitsubishiAC::on() {
void ICACHE_FLASH_ATTR IRMitsubishiAC::on() {
//state = ON;
remote_state[5] |= MITSUBISHI_AC_POWER;
}
// Set the requested power state of the A/C to off.
void IRMitsubishiAC::off() {
void ICACHE_FLASH_ATTR IRMitsubishiAC::off() {
//state = OFF;
remote_state[5] &= ~MITSUBISHI_AC_POWER;
}
// Set the requested power state of the A/C.
void IRMitsubishiAC::setPower(bool state) {
void ICACHE_FLASH_ATTR IRMitsubishiAC::setPower(bool state) {
if (state)
on();
else
@@ -71,25 +71,25 @@ void IRMitsubishiAC::setPower(bool state) {
}
// Return the requested power state of the A/C.
bool IRMitsubishiAC::getPower() {
bool ICACHE_FLASH_ATTR IRMitsubishiAC::getPower() {
return((remote_state[5] & MITSUBISHI_AC_POWER) != 0);
}
// Set the temp. in deg C
void IRMitsubishiAC::setTemp(uint8_t temp) {
void ICACHE_FLASH_ATTR IRMitsubishiAC::setTemp(uint8_t temp) {
temp = max(MITSUBISHI_AC_MIN_TEMP, temp);
temp = min(MITSUBISHI_AC_MAX_TEMP, temp);
remote_state[7] = temp - MITSUBISHI_AC_MIN_TEMP;
}
// Return the set temp. in deg C
uint8_t IRMitsubishiAC::getTemp() {
uint8_t ICACHE_FLASH_ATTR IRMitsubishiAC::getTemp() {
return(remote_state[7] + MITSUBISHI_AC_MIN_TEMP);
}
// Set the speed of the fan, 0-6.
// 0 is auto, 1-5 is the speed, 6 is silent.
void IRMitsubishiAC::setFan(uint8_t fan) {
void ICACHE_FLASH_ATTR IRMitsubishiAC::setFan(uint8_t fan) {
// Bounds check
if (fan > MITSUBISHI_AC_FAN_SILENT)
fan = MITSUBISHI_AC_FAN_MAX; // Set the fan to maximum if out of range.
@@ -103,7 +103,7 @@ void IRMitsubishiAC::setFan(uint8_t fan) {
}
// Return the requested state of the unit's fan.
uint8_t IRMitsubishiAC::getFan() {
uint8_t ICACHE_FLASH_ATTR IRMitsubishiAC::getFan() {
uint8_t fan = remote_state[9] & B111;
if (fan == MITSUBISHI_AC_FAN_MAX)
return MITSUBISHI_AC_FAN_SILENT;
@@ -111,7 +111,7 @@ uint8_t IRMitsubishiAC::getFan() {
}
// Return the requested climate operation mode of the a/c unit.
uint8_t IRMitsubishiAC::getMode() {
uint8_t ICACHE_FLASH_ATTR IRMitsubishiAC::getMode() {
/*
MITSUBISHI_AC_AUTO
MITSUBISHI_AC_COOL
@@ -122,7 +122,7 @@ uint8_t IRMitsubishiAC::getMode() {
}
// Set the requested climate operation mode of the a/c unit.
void IRMitsubishiAC::setMode(uint8_t mode) {
void ICACHE_FLASH_ATTR IRMitsubishiAC::setMode(uint8_t mode) {
// If we get an unexpected mode, default to AUTO.
switch (mode) {
case MITSUBISHI_AC_AUTO: break;
@@ -135,7 +135,7 @@ void IRMitsubishiAC::setMode(uint8_t mode) {
}
// Set the requested vane operation mode of the a/c unit.
void IRMitsubishiAC::setVane(uint8_t mode) {
void ICACHE_FLASH_ATTR IRMitsubishiAC::setVane(uint8_t mode) {
mode = max(mode, B111); // bounds check
mode |= B1000;
mode <<= 3;
@@ -143,6 +143,6 @@ void IRMitsubishiAC::setVane(uint8_t mode) {
}
// Return the requested vane operation mode of the a/c unit.
uint8_t IRMitsubishiAC::getVane() {
uint8_t ICACHE_FLASH_ATTR IRMitsubishiAC::getVane() {
return ((remote_state[9] & B00111000) >> 3);
}
File diff suppressed because it is too large Load Diff
+40 -28
View File
@@ -32,6 +32,7 @@
#define IRremote_h
#include <stdint.h>
#include "IRremoteInt.h"
// The following are compile-time library options.
// If you change them, recompile the library.
@@ -68,7 +69,8 @@ enum decode_type_t {
DENON,
KELVINATOR,
SHERWOOD,
MITSUBISHI_AC
MITSUBISHI_AC,
RCMM
};
// Results returned from the decoder
@@ -89,30 +91,33 @@ public:
// Decoded value for NEC when a repeat code is received
#define REPEAT 0xffffffff
#define SEND_PROTOCOL_NEC case NEC: sendNEC(data, nbits); break;
#define SEND_PROTOCOL_SONY case SONY: sendSony(data, nbits); break;
#define SEND_PROTOCOL_RC5 case RC5: sendRC5(data, nbits); break;
#define SEND_PROTOCOL_RC6 case RC6: sendRC6(data, nbits); break;
#define SEND_PROTOCOL_DISH case DISH: sendDISH(data, nbits); break;
#define SEND_PROTOCOL_JVC case JVC: sendJVC(data, nbits, 0); break;
#define SEND_PROTOCOL_SAMSUNG case SAMSUNG: sendSAMSUNG(data, nbits); break;
#define SEND_PROTOCOL_LG case LG: sendLG(data, nbits); break;
#define SEND_PROTOCOL_WHYNTER case WHYNTER: sendWhynter(data, nbits); break;
#define SEND_PROTOCOL_COOLIX case COOLIX: sendCOOLIX(data, nbits); break;
#define SEND_PROTOCOL_DENON case DENON: sendDenon(data, nbits); break;
#define SEND_PROTOCOL_NEC case NEC: sendNEC(data, nbits); break;
#define SEND_PROTOCOL_SONY case SONY: sendSony(data, nbits); break;
#define SEND_PROTOCOL_RC5 case RC5: sendRC5(data, nbits); break;
#define SEND_PROTOCOL_RC6 case RC6: sendRC6(data, nbits); break;
#define SEND_PROTOCOL_DISH case DISH: sendDISH(data, nbits); break;
#define SEND_PROTOCOL_JVC case JVC: sendJVC(data, nbits, 0); break;
#define SEND_PROTOCOL_SAMSUNG case SAMSUNG: sendSAMSUNG(data, nbits); break;
#define SEND_PROTOCOL_LG case LG: sendLG(data, nbits); break;
#define SEND_PROTOCOL_WHYNTER case WHYNTER: sendWhynter(data, nbits); break;
#define SEND_PROTOCOL_COOLIX case COOLIX: sendCOOLIX(data, nbits); break;
#define SEND_PROTOCOL_DENON case DENON: sendDenon(data, nbits); break;
#define SEND_PROTOCOL_SHERWOOD case SHERWOOD: sendSherwood(data, nbits); break;
#define SEND_PROTOCOL_RCMM case RCMM: sendRCMM(data, nbits); break;
// main class for receiving IR
class IRrecv
{
public:
IRrecv(int recvpin);
bool decode(decode_results *results);
bool decode(decode_results *results, irparams_t *save=NULL);
void enableIRIn();
void disableIRIn();
void resume();
private:
// These are called by decode
void copyIrParams(irparams_t *dest);
int getRClevel(decode_results *results, int *offset, int *used, int t1);
bool decodeNEC(decode_results *results);
bool decodeSony(decode_results *results);
@@ -120,6 +125,7 @@ public:
bool decodeMitsubishi(decode_results *results);
bool decodeRC5(decode_results *results);
bool decodeRC6(decode_results *results);
bool decodeRCMM(decode_results *results);
bool decodePanasonic(decode_results *results);
bool decodeLG(decode_results *results);
bool decodeJVC(decode_results *results);
@@ -131,6 +137,14 @@ public:
bool decodeDaikin(decode_results *results);
bool decodeDenon(decode_results *results);
int compare(unsigned int oldval, unsigned int newval);
uint32_t ticksLow(uint32_t usecs, uint8_t tolerance=TOLERANCE);
uint32_t ticksHigh(uint32_t usecs, uint8_t tolerance=TOLERANCE);
bool match(uint32_t measured_ticks, uint32_t desired_us,
uint8_t tolerance=TOLERANCE);
bool matchMark(uint32_t measured_ticks, uint32_t desired_us,
uint8_t tolerance=TOLERANCE, int excess=MARK_EXCESS);
bool matchSpace(uint32_t measured_ticks, uint32_t desired_us,
uint8_t tolerance=TOLERANCE, int excess=MARK_EXCESS);
};
// Only used for testing; can remove virtual for shorter code
@@ -139,6 +153,7 @@ public:
#else
#define VIRTUAL
#endif
class IRsend
{
public:
@@ -158,12 +173,13 @@ public:
SEND_PROTOCOL_COOLIX
SEND_PROTOCOL_DENON
SEND_PROTOCOL_SHERWOOD
SEND_PROTOCOL_RCMM
}
};
void sendCOOLIX(unsigned long data, int nbits);
void sendWhynter(unsigned long data, int nbits);
void sendNEC(unsigned long data, int nbits=32, unsigned int repeat=0);
void sendLG(unsigned long data, int nbits);
void sendLG(unsigned long data, int nbits=28, unsigned int repeat=0);
// sendSony() should typically be called with repeat=2 as Sony devices
// expect the code to be sent at least 3 times. (code + 2 repeats = 3 codes)
// As the legacy use of this procedure was only to send a single code
@@ -176,15 +192,19 @@ public:
void sendGC(unsigned int buf[], int len);
void sendRC5(unsigned long data, int nbits);
void sendRC6(unsigned long data, int nbits);
void sendDISH(unsigned long data, int nbits);
void sendRCMM(uint32_t data, uint8_t nbits=24);
// sendDISH() should typically be called with repeat=3 as DISH devices
// expect the code to be sent at least 4 times. (code + 3 repeats = 4 codes)
// As the legacy use of this procedure was only to send a single code
// it defaults to repeat=0 for backward compatiblity.
void sendDISH(unsigned long data, int nbits, unsigned int repeat=0);
void sendSharp(unsigned int address, unsigned int command);
void sendSharpRaw(unsigned long data, int nbits);
void sendPanasonic(unsigned int address, unsigned long data);
void sendJVC(unsigned long data, int nbits, int repeat); // *Note instead of sending the REPEAT constant if you want the JVC repeat signal sent, send the original code value and change the repeat argument from 0 to 1. JVC protocol repeats by skipping the header NOT by sending a separate code value like NEC does.
void sendSAMSUNG(unsigned long data, int nbits);
void sendDaikin(unsigned char daikin[]);
void sendDaikinChunk(unsigned char buf[], int len, int start);
void sendDenon(unsigned long data, int nbits);
void sendJVC(unsigned long data, int nbits, unsigned int repeat=0);
void sendSAMSUNG(unsigned long data, int nbits=32);
void sendDaikin(unsigned char data[]);
void sendDenon(unsigned long data, int nbits=14);
void sendKelvinator(unsigned char data[]);
void sendSherwood(unsigned long data, int nbits=32, unsigned int repeat=1);
void sendMitsubishiAC(unsigned char data[]);
@@ -210,12 +230,4 @@ private:
uint32_t start;
};
// Some useful constants
#define USECPERTICK 50 // microseconds per clock interrupt tick
#define RAWBUF 100 // Length of raw duration buffer
// Marks tend to be 100us too long, and spaces 100us too short
// when received due to sensor lag.
#define MARK_EXCESS 100
#endif
+41 -19
View File
@@ -60,10 +60,11 @@
#define NEC_RPT_SPACE 2250
#define NEC_MIN_COMMAND_LENGTH 108000UL
// Timings based on http://www.sbprojects.com/knowledge/ir/sirc.php
#define SONY_HDR_MARK 2400
#define SONY_HDR_SPACE 600
#define SONY_ONE_MARK 1200
#define SONY_ZERO_MARK 600
#define SONY_ONE_MARK 1250 // Experiments suggest +50 to spec is better.
#define SONY_ZERO_MARK 650 // Experiments suggest +50 to spec is better.
#define SONY_RPT_LENGTH 45000
#define SONY_DOUBLE_SPACE_USECS 500 // usually see 713 - not using ticks as get number wrapround
@@ -105,6 +106,20 @@
#define RC6_T1 444
#define RC6_RPT_LENGTH 46000
// http://www.sbprojects.com/knowledge/ir/rcmm.php
#define RCMM_HDR_MARK 416
#define RCMM_HDR_SPACE 277
#define RCMM_BIT_MARK 166
#define RCMM_BIT_SPACE_0 277
#define RCMM_BIT_SPACE_1 444
#define RCMM_BIT_SPACE_2 611
#define RCMM_BIT_SPACE_3 777
#define RCMM_RPT_LENGTH 27778
#define RCMM_MIN_GAP 3360
// Use a tolerance of +/-10% when matching some data spaces.
#define RCMM_TOLERANCE 10
#define RCMM_EXCESS 50
#define SHARP_BIT_MARK 245
#define SHARP_ONE_SPACE 1805
#define SHARP_ZERO_SPACE 795
@@ -118,13 +133,13 @@
#define DISH_ONE_SPACE 1700
#define DISH_ZERO_SPACE 2800
#define DISH_RPT_SPACE 6200
#define DISH_TOP_BIT 0x8000
#define PANASONIC_HDR_MARK 3502
#define PANASONIC_HDR_SPACE 1750
#define PANASONIC_BIT_MARK 502
#define PANASONIC_ONE_SPACE 1244
#define PANASONIC_ZERO_SPACE 400
// Ref: http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?26152
#define PANASONIC_HDR_MARK 3456
#define PANASONIC_HDR_SPACE 1728
#define PANASONIC_BIT_MARK 432
#define PANASONIC_ONE_SPACE 1296
#define PANASONIC_ZERO_SPACE 432
#define JVC_HDR_MARK 8000
#define JVC_HDR_SPACE 4000
@@ -184,15 +199,18 @@
#define KELVINATOR_GAP_SPACE 19950U
#define KELVINATOR_CMD_FOOTER 2U
#define TOLERANCE 25 // percent tolerance in measurements
#define LTOL (1.0 - TOLERANCE/100.)
#define UTOL (1.0 + TOLERANCE/100.)
// Some useful constants
#define USECPERTICK 50 // microseconds per clock interrupt tick
#define RAWBUF 100 // Length of raw duration buffer
// Marks tend to be 100us too long, and spaces 100us too short
// when received due to sensor lag.
#define MARK_EXCESS 100
#define _GAP 5000 // Minimum map between transmissions
#define GAP_TICKS (_GAP/USECPERTICK)
#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK))
#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))
#define TOLERANCE 25 // default percent tolerance in measurements
// receiver states
#define STATE_IDLE 2
@@ -200,14 +218,18 @@
#define STATE_SPACE 4
#define STATE_STOP 5
#define RAWBUF 100 // Length of raw duration buffer
// information for the interrupt handler
typedef struct {
uint8_t recvpin; // pin for IR data from detector
uint8_t rcvstate; // state machine
unsigned int timer; // state timer, counts 50uS ticks.
unsigned int rawbuf[RAWBUF]; // raw data
uint8_t rawlen; // counter of entries in rawbuf
uint8_t overflow;
uint8_t recvpin; // pin for IR data from detector
uint8_t rcvstate; // state machine
unsigned int timer; // state timer, counts 50uS ticks.
unsigned int rawbuf[RAWBUF]; // raw data
// uint16_t is used for rawlen as it saves 3 bytes of iram in the interrupt
// handler. Don't ask why, I don't know. It just does.
uint16_t rawlen; // counter of entries in rawbuf.
uint8_t overflow; // Buffer overflow indicator.
}
irparams_t;
+9
View File
@@ -18,6 +18,15 @@ Seb's notes : I also changed the pulse parameters for Samsung, update the Panaso
5. Restart your Arduino ide
6. Check out the examples
###### Using Git to install library ( Linux )
```
cd ~/Arduino/libraries
git clone https://github.com/markszabo/IRremoteESP8266.git
```
###### To Update to the latest version of the library
`
cd ~/Arduino/libraries/IRremoteESP8266 && git pull
`
## Contributing
If you want to contribute to this project:
- Report bugs and errors
@@ -26,7 +26,7 @@ void handleIr(){
for (uint8_t i=0; i<server.args(); i++){
if(server.argName(i) == "code")
{
unsigned long code = server.arg(i).toInt();
unsigned long code = strtoul(server.arg(i).c_str(), NULL, 10);
irsend.sendNEC(code, 32);
}
}
@@ -1,33 +1,39 @@
/*
* IRremoteESP8266: IRrecvDumpV2 - dump details of IR codes with IRrecv
* An IR detector/demodulator must be connected to the input RECV_PIN.
* Version 0.1 Sept, 2015
* Example circuit diagram:
* https://github.com/markszabo/IRremoteESP8266/wiki#ir-receiving
* Changes:
* Version 0.2 April, 2017
* - Decode from a copy of the data so we can start capturing faster thus
* reduce the likelihood of miscaptures.
* Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009, Copyright 2009 Ken Shirriff, http://arcfn.com
*/
#include <IRremoteESP8266.h>
int RECV_PIN = 2; //an IR detector/demodulator is connected to GPIO pin 2
// An IR detector/demodulator is connected to GPIO pin 14(D5 on a NodeMCU board).
int RECV_PIN = 14;
IRrecv irrecv(RECV_PIN);
void setup ( )
{
Serial.begin(9600); // Status message will be sent to PC at 9600 baud
decode_results results; // Somewhere to store the results
irparams_t save; // A place to copy the interrupt state while decoding.
void setup() {
Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY); // Status message will be sent to the PC at 115200 baud
irrecv.enableIRIn(); // Start the receiver
}
//+=============================================================================
// Display IR code
//
void ircode (decode_results *results)
{
void ircode(decode_results *results) {
// Panasonic has an Address
if (results->decode_type == PANASONIC) {
Serial.print(results->panasonicAddress, HEX);
Serial.print(":");
}
// Print Code
Serial.print(results->value, HEX);
}
@@ -35,8 +41,7 @@ void ircode (decode_results *results)
//+=============================================================================
// Display encoding type
//
void encoding (decode_results *results)
{
void encoding(decode_results *results) {
switch (results->decode_type) {
default:
case UNKNOWN: Serial.print("UNKNOWN"); break ;
@@ -54,14 +59,14 @@ void encoding (decode_results *results)
case WHYNTER: Serial.print("WHYNTER"); break ;
case AIWA_RC_T501: Serial.print("AIWA_RC_T501"); break ;
case PANASONIC: Serial.print("PANASONIC"); break ;
case DENON: Serial.print("DENON"); break ;
}
}
//+=============================================================================
// Dump out the decode_results structure.
//
void dumpInfo (decode_results *results)
{
void dumpInfo (decode_results *results) {
if (results->overflow) {
Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWBUF");
return;
@@ -83,8 +88,7 @@ void dumpInfo (decode_results *results)
//+=============================================================================
// Dump out the decode_results structure.
//
void dumpRaw (decode_results *results)
{
void dumpRaw(decode_results *results) {
// Print Raw data
Serial.print("Timing[");
Serial.print(results->rawlen-1, DEC);
@@ -113,8 +117,7 @@ void dumpRaw (decode_results *results)
//+=============================================================================
// Dump out the decode_results structure.
//
void dumpCode (decode_results *results)
{
void dumpCode (decode_results *results) {
// Start declaration
Serial.print("unsigned int "); // variable type
Serial.print("rawData["); // array name
@@ -129,7 +132,7 @@ void dumpCode (decode_results *results)
}
// End declaration
Serial.print("};"); //
Serial.print("};"); //
// Comment
Serial.print(" // ");
@@ -142,7 +145,6 @@ void dumpCode (decode_results *results)
// Now dump "known" codes
if (results->decode_type != UNKNOWN) {
// Some protocols have an address
if (results->decode_type == PANASONIC) {
Serial.print("unsigned int addr = 0x");
@@ -160,15 +162,12 @@ void dumpCode (decode_results *results)
//+=============================================================================
// The repeating section of the code
//
void loop ( )
{
decode_results results; // Somewhere to store the results
if (irrecv.decode(&results)) { // Grab an IR code
void loop() {
// Check if the IR code has been received.
if (irrecv.decode(&results, &save)) {
dumpInfo(&results); // Output the results
dumpRaw(&results); // Output the results in RAW format
dumpCode(&results); // Output the results as source code
Serial.println(""); // Blank line between entries
irrecv.resume(); // Prepare for the next value
}
}
@@ -1,18 +1,40 @@
/*
* IRremoteESP8266: IRsendDemo - demonstrates sending IR codes with IRsend
* An IR LED must be connected to ESP8266 pin 0.
* Version 0.1 June, 2015
* IRremoteESP8266: IRsendDemo - demonstrates sending IR codes with IRsend.
*
* An IR LED circuit *MUST* be connected to ESP8266 pin 4 (D2).
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
* Suggested circuit:
* https://github.com/markszabo/IRremoteESP8266/wiki#ir-sending
*
* Common mistakes & tips:
* * Don't just connect the IR LED directly to the pin, it won't
* have enough current to drive the IR LED effectively.
* * Make sure you have the IR LED polarity correct.
* See: https://learn.sparkfun.com/tutorials/polarity/diode-and-led-polarity
* * Typical digital camera/phones can be used to see if the IR LED is flashed.
* Replace the IR LED with a normal LED if you don't have a digital camera
* when debugging.
* * Avoid using the following pins unless you really know what you are doing:
* * Pin 0/D3: Can interfere with the boot/program mode & support circuits.
* * Pin 1/TX/TXD0: Any serial transmissions from the ESP8266 will interfere.
* * Pin 3/RX/RXD0: Any serial transmissions to the ESP8266 will interfere.
* * ESP-01 modules are tricky. We suggest you use a module with more GPIOs
* for your first time. e.g. ESP-12 etc.
*
* Version 1.0 April, 2017
* Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009, Copyright 2009 Ken Shirriff, http://arcfn.com
*/
#include <IRremoteESP8266.h>
IRsend irsend(0); //an IR led is connected to GPIO pin 0
IRsend irsend(4); //an IR led is connected to GPIO pin 4 (D2)
void setup()
{
irsend.begin();
Serial.begin(9600);
Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY);
}
void loop() {
@@ -20,6 +42,6 @@ void loop() {
irsend.sendNEC(0x00FFE01FUL, 32);
delay(2000);
Serial.println("Sony");
irsend.sendSony(0xa90, 12);
irsend.sendSony(0xa90, 12, 2);
delay(2000);
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "IRremoteESP8266",
"version": "1.0.2",
"version": "1.2.0",
"keywords": "infrared, ir, remote, esp8266",
"description": "Send and receive infrared signals with multiple protocols (ESP8266)",
"repository":
+1 -1
View File
@@ -1,5 +1,5 @@
name=IRremoteESP8266
version=1.0.2
version=1.2.0
author=Sebastien Warin, Mark Szabo, Ken Shirriff, David Conran
maintainer=Mark Szabo, David Conran, Sebastien Warin, Roi Dayan, Massimiliano Pinto
sentence=Send and receive infrared signals with multiple protocols (ESP8266)
+165
View File
@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
+241
View File
@@ -0,0 +1,241 @@
/*-------------------------------------------------------------------------
Arduino library to ...
Written by Jochen Krapf,
contributions by ... and other members of the open
source community.
-------------------------------------------------------------------------
This file is part of the MechInputs library.
MechInputs is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
MechInputs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with MechInputs. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include "QEIx4.h"
#include <limits.h>
// bit masks for state machine - don't change!!!
#define QEIx4_STATE 0xC
#define QEIx4_MASK 0x1C
#define QEIx4_1x_INC 0x0100
#define QEIx4_2x_INC 0x0200
#define QEIx4_4x_INC 0x0400
#define QEIx4_1x_DEC 0x1000
#define QEIx4_2x_DEC 0x2000
#define QEIx4_4x_DEC 0x4000
#define QEIx4_1x_MASK 0x11FF
#define QEIx4_2x_MASK 0x33FF
#define QEIx4_4x_MASK 0x77FF
#define QEIx4_DIR 0x20
#define QEIx4_A 1
#define QEIx4_B 2
#define QEIx4_AB 3
#define QEIx4_S0 0x0
#define QEIx4_S1 0x4
#define QEIx4_S2 0x8
#define QEIx4_S3 0xC
#define QEIx4_CCW 0
#define QEIx4_CW 0x10
#define QEIx4_IS_CHG 0x7700
#define QEIx4_IS_INC 0x0700
#define QEIx4_IS_DEC 0x7000
#define QEIx4_IS_DIR 0x20
// state machine for decoting - don't change!!!
uint16_t QEIx4::__stateLUT[32] = {
// act state S0 in CCW direction
QEIx4_CCW | QEIx4_S0,
QEIx4_CW | QEIx4_S1 | QEIx4_A | QEIx4_4x_INC | QEIx4_DIR,
QEIx4_CCW | QEIx4_S0 | QEIx4_B,
QEIx4_CCW | QEIx4_S3 | QEIx4_AB | QEIx4_1x_DEC,
// act state S1 in CCW direction
QEIx4_CCW | QEIx4_S1,
QEIx4_CCW | QEIx4_S1 | QEIx4_A,
QEIx4_CCW | QEIx4_S0 | QEIx4_B | QEIx4_4x_DEC,
QEIx4_CW | QEIx4_S2 | QEIx4_AB | QEIx4_1x_INC | QEIx4_DIR,
// act state S2 in CCW direction
QEIx4_CCW | QEIx4_S1 | QEIx4_2x_DEC,
QEIx4_CCW | QEIx4_S2 | QEIx4_A,
QEIx4_CW | QEIx4_S3 | QEIx4_B | QEIx4_4x_INC | QEIx4_DIR,
QEIx4_CCW | QEIx4_S2 | QEIx4_AB,
// act state S3 in CCW direction
QEIx4_CW | QEIx4_S0 | QEIx4_2x_INC | QEIx4_DIR,
QEIx4_CCW | QEIx4_S2 | QEIx4_A | QEIx4_4x_DEC,
QEIx4_CCW | QEIx4_S3 | QEIx4_B,
QEIx4_CCW | QEIx4_S3 | QEIx4_AB,
// act state S0 in CW direction
QEIx4_CW | QEIx4_S0,
QEIx4_CW | QEIx4_S1 | QEIx4_A | QEIx4_4x_INC,
QEIx4_CW | QEIx4_S0 | QEIx4_B,
QEIx4_CCW | QEIx4_S3 | QEIx4_AB | QEIx4_1x_DEC | QEIx4_DIR,
// act state S1 in CW direction
QEIx4_CW | QEIx4_S1,
QEIx4_CW | QEIx4_S1 | QEIx4_A,
QEIx4_CCW | QEIx4_S0 | QEIx4_B | QEIx4_4x_DEC | QEIx4_DIR,
QEIx4_CW | QEIx4_S2 | QEIx4_AB | QEIx4_1x_INC,
// act state S2 in CW direction
QEIx4_CCW | QEIx4_S1 | QEIx4_2x_DEC | QEIx4_DIR,
QEIx4_CW | QEIx4_S2 | QEIx4_A,
QEIx4_CW | QEIx4_S3 | QEIx4_B | QEIx4_4x_INC,
QEIx4_CW | QEIx4_S2 | QEIx4_AB,
// act state S3 in CW direction
QEIx4_CW | QEIx4_S0 | QEIx4_2x_INC,
QEIx4_CCW | QEIx4_S2 | QEIx4_A | QEIx4_4x_DEC | QEIx4_DIR,
QEIx4_CW | QEIx4_S3 | QEIx4_B,
QEIx4_CW | QEIx4_S3 | QEIx4_AB
};
// Helper for ISR call
QEIx4* QEIx4::__instance[4] = { 0 };
//#define DEB(x) printf (x)
#define DEB(x)
///////////////////////////////////////////////////////////////////////////////
QEIx4::QEIx4()
{
for (byte i=0; i<4; i++)
if (__instance[i] == 0)
{
__instance[i] = this;
DEB("::");
break;
}
_pinA = -1;
_pinB = -1;
_pinI = -1;
_state = 0;
_limitMin = LONG_MIN;
_limitMax = LONG_MAX;
}
///////////////////////////////////////////////////////////////////////////////
QEIx4::~QEIx4()
{
for (byte i=0; i<4; i++)
if (__instance[i] == this)
{
__instance[i] = 0;
}
}
///////////////////////////////////////////////////////////////////////////////
void QEIx4::begin(int16_t pinA, int16_t pinB, int16_t pinI, uint8_t mode)
{
if (_pinA >= 0)
detachInterrupt(digitalPinToInterrupt(_pinA));
if (_pinB >= 0)
detachInterrupt(digitalPinToInterrupt(_pinB));
_pinA = pinA;
_pinB = pinB;
_pinI = pinI;
_counter = 0;
_bHasChanged = true;
if (mode == 1)
_eventMask = QEIx4_1x_MASK;
else if (mode == 2)
_eventMask = QEIx4_2x_MASK;
else
_eventMask = QEIx4_4x_MASK;
pinMode(_pinA, INPUT_PULLUP);
pinMode(_pinB, INPUT_PULLUP);
pinMode(_pinI, INPUT_PULLUP);
if (_pinA >= 0)
attachInterrupt(digitalPinToInterrupt(_pinA), ISR, CHANGE);
if (_pinB >= 0)
attachInterrupt(digitalPinToInterrupt(_pinB), ISR, CHANGE);
}
///////////////////////////////////////////////////////////////////////////////
long QEIx4::read()
{
noInterrupts();
_bHasChanged = false;
long ret = _counter;
interrupts();
return ret;
}
void QEIx4::loop()
{
noInterrupts();
processStateMachine();
interrupts();
}
///////////////////////////////////////////////////////////////////////////////
void QEIx4::processStateMachine()
{
DEB(".");
_state &= QEIx4_MASK;
if (digitalRead(_pinA)) _state |= QEIx4_A;
if (digitalRead(_pinB)) _state |= QEIx4_B;
_state = __stateLUT[_state]; // magic is done by lookup-table
_state &= _eventMask;
if (_state & QEIx4_IS_CHG) { // is any change?
bool bCounterChange = false;
if ((_state & QEIx4_IS_INC) && (_counter < _limitMax)) { // has moved foreward?
_counter++;
bCounterChange = true;
DEB("+");
}
if ((_state & QEIx4_IS_DEC) && (_counter > _limitMin)) { // has moved backward?
_counter--;
bCounterChange = true;
DEB("-");
}
if (_pinI >= 0 && _bIndexTrigger && bCounterChange && digitalRead(_pinI)) { // is index pin triggered?
_bIndexTrigger = false;
_counter = 0;
DEB("I");
}
if (bCounterChange) { // has counter changed?
_bHasChanged = true;
}
}
}
void QEIx4::ISR()
{
for (byte i=0; i<4; i++)
if (__instance[i])
{
__instance[i]->processStateMachine();
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
+133
View File
@@ -0,0 +1,133 @@
/*--------------------------------------------------------------------
Arduino library to ...
Written by Jochen Krapf,
contributions by ... and other members of the open
source community.
-------------------------------------------------------------------------
This file is part of the MechInputs library.
MechInputs is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
MechInputs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with MechInputs. If not, see
<http://www.gnu.org/licenses/>.
--------------------------------------------------------------------*/
#ifndef QEIX4_H
#define QEIX4_H
#if (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#include <pins_arduino.h>
#endif
class QEIx4
{
public:
/** constructor of QEIx4 object
*/
QEIx4();
/** destructor of QEIx4 object
*/
~QEIx4();
void begin(int16_t pinA, int16_t pinB, int16_t pinI=-1, uint8_t mode=4);
/** Gets the actual counter value.
*
* @return Actual counter value
*/
long read();
/** Gets the actual counter value as long operator.
*
* @return Actual counter value as long operator
*/
operator long() { // int-Operator
return read();
}
/** Sets the counter value at actual encoder position to given value.
*
* @param Counter value
*/
void write(long counter) {
_counter = counter;
}
/** Sets the counter value at actual encoder position to given value as assign operator.
*
* @param Counter value
*/
int operator= (long counter) { // Assign-Operator
write(counter);
return counter;
}
void setLimit(long limitMin, long limitMax)
{
_limitMin = limitMin;
_limitMax = limitMax;
}
/** Sets the flag for zeroing on next high on index pin while AB lines triggers next counting. The trigger calls tha callback function in which the counter can be set to zero or the actual counter can be latched in for later offset calculation
*
* @param Flag for triggering. Set to 1 for call the attached callback. It is reseted after this call
*/
void setIndexTrigger(bool bIndexTrigger=true) {
if (_pinI < 0)
bIndexTrigger = false;
_bIndexTrigger = bIndexTrigger;
}
bool hasChanged(){
return _bHasChanged;
}
void loop();
protected:
/** Polls the state machine and updates the counter value.
*/
void processStateMachine();
/** Entry point for arduino interrupts - route to class instances
*/
static void ISR();
protected:
volatile long _counter;
volatile bool _bHasChanged;
volatile bool _bIndexTrigger;
int16_t _pinA;
int16_t _pinB;
int16_t _pinI;
long _limitMin;
long _limitMax;
uint16_t _state;
uint16_t _eMode;
private:
static uint16_t __stateLUT[32];
static QEIx4* __instance[4];
uint16_t _eventMask;
};
#endif // QEIX4_H
+28
View File
@@ -0,0 +1,28 @@
# MechInputs Library (https://github.com/jkDesignDE/MechInputs)
Arduino library for reading and debouncing mechanical inputs Like buttons, switches and encoders.
After downloading, rename folder to 'MechInputs' and install in Arduino Libraries folder. Restart Arduino IDE, then open File->Sketchbook->Library->MechInputs->* sketches.
# QEI (quadrature encoder interface) library, for decoding AB signals from a rotary encoder
Use cases:
- Rotary encoder in closed loop motor regulation
- Hand wheel
- Input device for motion control (MoCo)
A class to decode pulses on a rotary encoder with AB signals (quadrature encoder).
It uses all 4 edges of the AB signals to increase the counter resolution 4 times of cycles per rotation/revolution (CPR) (e.g. an encoder with 500 CPR get 2000 counts per rotation)
In opposite to most common QEI implementation this is resistant to jitter and chatter on AB signals and motor vibrations.
Whes reaching the next position the edge that triggerd this position (state) is ignored to aboid oscillating up/down counts.
It can also be used in polling mode i.g. in idle routines if interrupts are not desired.
At this mode be sure that the sampling frequency is heigher than the maximum rotation speed (expeced counts per second)
The internal state machine is based on a look up table (LUT) to minimize interrupt retention time and get all necessary flags at once.
The library is designed to support closed loop speed- and motion-controller for also slow and smooth motions like movie camera motion control.
+9
View File
@@ -0,0 +1,9 @@
name=MechInputs
version=0.0.1
author=Jochen Krapf
maintainer=Jochen Krapf <jk@nerd2nerd.org>
sentence=Library for Reading and Debouncing Mechanical Inputs Like Buttons, Switches and Encoders with Arduino-Based Controllers.
paragraph=Library for Reading and Debouncing Mechanical Inputs Like Buttons, Switches and Encoders with Arduino-Based Controllers.
category=Input
url=https://github.com/jkDesignDE/MechInputs
architectures=esp8266,avr
+22
View File
@@ -0,0 +1,22 @@
# SDS011
Arduino library for dust Sensor SDS011 (Nova Fitness Co.,Ltd)
This library uses SoftSerial to connect to the SDS011.
## Usage
* Define SDS object:
SDS011(uint8_t pin_rx, uint8_t pin_tx);
i.e. SDS011 mySDS(pinRX,pinTX);
* Start object:
void begin(void);
i.e. mySDS.begin();
* Read values:
int read(float *p25, float *p10);
i.e. error = mySDS(pm25,pm10);
Reads the PM2.5 and PM10 values, return code is 0, if new values were read, and 1 if there were no new values.
+110
View File
@@ -0,0 +1,110 @@
// SDS011 dust sensor PM2.5 and PM10
// ---------------------
//
// By R. Zschiegner (rz@madavi.de)
// April 2016
//
// Documentation:
// - The iNovaFitness SDS011 datasheet
//
#include "SDS011.h"
static const byte SLEEPCMD[19] = {
0xAA, // head
0xB4, // command id
0x06, // data byte 1
0x01, // data byte 2 (set mode)
0x00, // data byte 3 (sleep)
0x00, // data byte 4
0x00, // data byte 5
0x00, // data byte 6
0x00, // data byte 7
0x00, // data byte 8
0x00, // data byte 9
0x00, // data byte 10
0x00, // data byte 11
0x00, // data byte 12
0x00, // data byte 13
0xFF, // data byte 14 (device id byte 1)
0xFF, // data byte 15 (device id byte 2)
0x05, // checksum
0xAB // tail
};
SDS011::SDS011(void) {
}
// --------------------------------------------------------
// SDS011:read
// --------------------------------------------------------
int SDS011::read(float *p25, float *p10) {
byte buffer;
int value;
int len = 0;
int pm10_serial = 0;
int pm25_serial = 0;
int checksum_is;
int checksum_ok = 0;
int error = 1;
while ((sds_data->available() > 0) && (sds_data->available() >= (10-len))) {
buffer = sds_data->read();
value = int(buffer);
switch (len) {
case (0): if (value != 170) { len = -1; }; break;
case (1): if (value != 192) { len = -1; }; break;
case (2): pm25_serial = value; checksum_is = value; break;
case (3): pm25_serial += (value << 8); checksum_is += value; break;
case (4): pm10_serial = value; checksum_is += value; break;
case (5): pm10_serial += (value << 8); checksum_is += value; break;
case (6): checksum_is += value; break;
case (7): checksum_is += value; break;
case (8): if (value == (checksum_is % 256)) { checksum_ok = 1; } else { len = -1; }; break;
case (9): if (value != 171) { len = -1; }; break;
}
len++;
if (len == 10 && checksum_ok == 1) {
*p10 = (float)pm10_serial/10.0;
*p25 = (float)pm25_serial/10.0;
len = 0; checksum_ok = 0; pm10_serial = 0.0; pm25_serial = 0.0; checksum_is = 0;
error = 0;
}
yield();
}
return error;
}
// --------------------------------------------------------
// SDS011:sleep
// --------------------------------------------------------
void SDS011::sleep() {
for (uint8_t i = 0; i < 19; i++) {
sds_data->write(SLEEPCMD[i]);
}
sds_data->flush();
while (sds_data->available() > 0) {
sds_data->read();
}
}
// --------------------------------------------------------
// SDS011:wakeup
// --------------------------------------------------------
void SDS011::wakeup() {
sds_data->write(0x01);
sds_data->flush();
}
void SDS011::begin(uint8_t pin_rx, uint8_t pin_tx) {
_pin_rx = pin_rx;
_pin_tx = pin_tx;
SoftwareSerial *softSerial = new SoftwareSerial(_pin_rx, _pin_tx);
//Initialize the 'Wire' class for I2C-bus communication.
softSerial->begin(9600);
sds_data = softSerial;
}
+30
View File
@@ -0,0 +1,30 @@
// SDS011 dust sensor PM2.5 and PM10
// ---------------------------------
//
// By R. Zschiegner (rz@madavi.de)
// April 2016
//
// Documentation:
// - The iNovaFitness SDS011 datasheet
//
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <SoftwareSerial.h>
class SDS011 {
public:
SDS011(void);
void begin(uint8_t pin_rx, uint8_t pin_tx);
int read(float *p25, float *p10);
void sleep();
void wakeup();
private:
uint8_t _pin_rx, _pin_tx;
Stream *sds_data;
};
@@ -0,0 +1,26 @@
// SDS011 dust sensor example
// -----------------------------
//
// By R. Zschiegner (rz@madavi.de).
// April 2016
#include <SDS011.h>
float p10,p25;
int error;
SDS011 my_sds;
void setup() {
my_sds.begin(D1,D2);
Serial.begin(9600);
}
void loop() {
error = my_sds.read(&p25,&p10);
if (! error) {
Serial.println("P2.5: "+String(p25));
Serial.println("P10: "+String(p10));
}
delay(100);
}
+9
View File
@@ -0,0 +1,9 @@
name=SDS011 sensor Library
version=0.0.5
author=R. Zschiegner
maintainer=R.Zschiegner <rz@madavi.de>
sentence=Nova Fitness SDS011 dust sensor library
paragraph=Nova Fitness SDS011 dust sensor library
category=Sensors
url=https://github.com/ricki-z/SDS011
architectures=esp8266,avr
@@ -0,0 +1,9 @@
License Information
-------------------
The hardware is released under [Creative Commons Share-alike 3.0](http://creativecommons.org/licenses/by-sa/3.0/).
All other code is open source so please feel free to do anything you want with it; you buy me a beer if you use this and we meet someday ([Beerware license](http://en.wikipedia.org/wiki/Beerware)).
@@ -0,0 +1,82 @@
SparkFun APDS9960 RGB and Gesture Sensor Arduino Library
=========================================================
![Avago APDS-9960 Breakout Board - SEN-12787 ](https://cdn.sparkfun.com/r/92-92/assets/parts/9/6/0/3/12787-01.jpg)
[*Avago APDS-9960 Breakout Board (SEN-12787)*](https://www.sparkfun.com/products/12787)
Getting Started
---------------
* Download the Git repository as a ZIP ("Download ZIP" button)
* Unzip
* Copy the entire library directory (APDS-9960_RGB_and_Gesture_Sensor_Arduino_Library
) to \<Arduino installation directory\>/libraries
* Open the Arduino program
* Select File -> Examples -> SparkFun_APDS9960 -> GestureTest
* Plug in your Arduino and APDS-9960 with the following connections
*-OR-*
* Use the library manager
| Arduino Pin | APDS-9960 Board | Function |
|---|---|---|
| 3.3V | VCC | Power |
| GND | GND | Ground |
| A4 | SDA | I2C Data |
| A5 | SCL | I2C Clock |
| 2 | INT | Interrupt |
* Go to Tools -> Board and select your Arduino board
* Go to Tools -> Serial Port and select the COM port of your Arduino board
* Click "Upload"
* Go to Tools -> Serial Monitor
* Ensure the baud rate is set at 9600 baud
* Swipe your hand over the sensor in various directions!
Repository Contents
-------------------
* **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE.
* **/src** - Source files for the library (.cpp, .h).
* **library.properties** - General library properties for the Arduino package manager.
Documentation
--------------
* **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library.
* **[Product Repository](https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor)** - Main repository (including hardware files) for the SparkFun_APDS9960 RGB and Gesture Sensor.
* **[Hookup Guide](https://learn.sparkfun.com/tutorials/apds-9960-rgb-and-gesture-sensor-hookup-guide)** - Basic hookup guide for the sensor.
Products that use this Library
---------------------------------
* [SEN-12787](https://www.sparkfun.com/products/12787)- Avago APDS-9960
Version History
---------------
* [V_1.4.1](https://github.com/sparkfun/SparkFun_APDS-9960_Sensor_Arduino_Library/tree/V_1.4.1) - Removing blank files, updating library.properties file.
* [V_1.4.0](https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor_Arduino_Library/tree/V_1.4.0) - Updated to new library structure
* V_1.3.0 - Implemented disableProximitySensor(). Thanks to jmg5150 for catching that!
* V_1.2.0 - Added pinMode line to GestureTest demo to fix interrupt bug with some Arduinos
* V_1.1.0 - Updated GestureTest demo to not freeze with fast swipes
* V_1.0.0: Initial release
* Ambient and RGB light sensing implemented
* Ambient light interrupts working
* Proximity sensing implemented
* Proximity interrupts working
* Gesture (UP, DOWN, LEFT, RIGHT, NEAR, FAR) sensing implemented
License Information
-------------------
This product is _**open source**_!
The **code** is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round!
Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release anything derivative under the same license.
Distributed as-is; no warranty is given.
- Your friends at SparkFun.
@@ -0,0 +1,161 @@
/****************************************************************
AmbientLightInterrupt.ino
APDS-9960 RGB and Gesture Sensor
Shawn Hymel @ SparkFun Electronics
October 24, 2014
https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
Tests the ambient light interrupt abilities of the APDS-9960.
Configures the APDS-9960 over I2C and waits for an external
interrupt based on high or low light conditions. Try covering
the sensor with your hand or bringing the sensor close to a
bright light source. You might need to adjust the LIGHT_INT_HIGH
and LIGHT_INT_LOW values to get the interrupt to work correctly.
Hardware Connections:
IMPORTANT: The APDS-9960 can only accept 3.3V!
Arduino Pin APDS-9960 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
2 INT Interrupt
13 - LED
Resources:
Include Wire.h and SparkFun_APDS-9960.h
Development environment specifics:
Written in Arduino 1.0.5
Tested with SparkFun Arduino Pro Mini 3.3V
This code is beerware; if you see me (or any other SparkFun
employee) at the local, and you've found our code helpful, please
buy us a round!
Distributed as-is; no warranty is given.
****************************************************************/
#include <Wire.h>
#include <SparkFun_APDS9960.h>
// Pins
#define APDS9960_INT 2 // Needs to be an interrupt pin
#define LED_PIN 13 // LED for showing interrupt
// Constants
#define LIGHT_INT_HIGH 1000 // High light level for interrupt
#define LIGHT_INT_LOW 10 // Low light level for interrupt
// Global variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
uint16_t ambient_light = 0;
uint16_t red_light = 0;
uint16_t green_light = 0;
uint16_t blue_light = 0;
int isr_flag = 0;
uint16_t threshold = 0;
void setup() {
// Set LED as output
pinMode(LED_PIN, OUTPUT);
pinMode(APDS9960_INT, INPUT);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("-------------------------------------"));
Serial.println(F("SparkFun APDS-9960 - Light Interrupts"));
Serial.println(F("-------------------------------------"));
// Initialize interrupt service routine
attachInterrupt(0, interruptRoutine, FALLING);
// Initialize APDS-9960 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9960 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9960 init!"));
}
// Set high and low interrupt thresholds
if ( !apds.setLightIntLowThreshold(LIGHT_INT_LOW) ) {
Serial.println(F("Error writing low threshold"));
}
if ( !apds.setLightIntHighThreshold(LIGHT_INT_HIGH) ) {
Serial.println(F("Error writing high threshold"));
}
// Start running the APDS-9960 light sensor (no interrupts)
if ( apds.enableLightSensor(false) ) {
Serial.println(F("Light sensor is now running"));
} else {
Serial.println(F("Something went wrong during light sensor init!"));
}
// Read high and low interrupt thresholds
if ( !apds.getLightIntLowThreshold(threshold) ) {
Serial.println(F("Error reading low threshold"));
} else {
Serial.print(F("Low Threshold: "));
Serial.println(threshold);
}
if ( !apds.getLightIntHighThreshold(threshold) ) {
Serial.println(F("Error reading high threshold"));
} else {
Serial.print(F("High Threshold: "));
Serial.println(threshold);
}
// Enable interrupts
if ( !apds.setAmbientLightIntEnable(1) ) {
Serial.println(F("Error enabling interrupts"));
}
// Wait for initialization and calibration to finish
delay(500);
}
void loop() {
// If interrupt occurs, print out the light levels
if ( isr_flag == 1 ) {
// Read the light levels (ambient, red, green, blue) and print
if ( !apds.readAmbientLight(ambient_light) ||
!apds.readRedLight(red_light) ||
!apds.readGreenLight(green_light) ||
!apds.readBlueLight(blue_light) ) {
Serial.println("Error reading light values");
} else {
Serial.print("Interrupt! Ambient: ");
Serial.print(ambient_light);
Serial.print(" R: ");
Serial.print(red_light);
Serial.print(" G: ");
Serial.print(green_light);
Serial.print(" B: ");
Serial.println(blue_light);
}
// Turn on LED for a half a second
digitalWrite(LED_PIN, HIGH);
delay(500);
digitalWrite(LED_PIN, LOW);
// Reset flag and clear APDS-9960 interrupt (IMPORTANT!)
isr_flag = 0;
if ( !apds.clearAmbientLightInt() ) {
Serial.println("Error clearing interrupt");
}
}
}
void interruptRoutine() {
isr_flag = 1;
}
@@ -0,0 +1,96 @@
/****************************************************************
ColorSensor.ino
APDS-9960 RGB and Gesture Sensor
Shawn Hymel @ SparkFun Electronics
October 15, 2014
https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
Tests the color and ambient light sensing abilities of the
APDS-9960. Configures APDS-9960 over I2C and polls the sensor for
ambient light and color levels, which are displayed over the
serial console.
Hardware Connections:
IMPORTANT: The APDS-9960 can only accept 3.3V!
Arduino Pin APDS-9960 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
Resources:
Include Wire.h and SparkFun_APDS-9960.h
Development environment specifics:
Written in Arduino 1.0.5
Tested with SparkFun Arduino Pro Mini 3.3V
This code is beerware; if you see me (or any other SparkFun
employee) at the local, and you've found our code helpful, please
buy us a round!
Distributed as-is; no warranty is given.
****************************************************************/
#include <Wire.h>
#include <SparkFun_APDS9960.h>
// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
uint16_t ambient_light = 0;
uint16_t red_light = 0;
uint16_t green_light = 0;
uint16_t blue_light = 0;
void setup() {
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("--------------------------------"));
Serial.println(F("SparkFun APDS-9960 - ColorSensor"));
Serial.println(F("--------------------------------"));
// Initialize APDS-9960 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9960 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9960 init!"));
}
// Start running the APDS-9960 light sensor (no interrupts)
if ( apds.enableLightSensor(false) ) {
Serial.println(F("Light sensor is now running"));
} else {
Serial.println(F("Something went wrong during light sensor init!"));
}
// Wait for initialization and calibration to finish
delay(500);
}
void loop() {
// Read the light levels (ambient, red, green, blue)
if ( !apds.readAmbientLight(ambient_light) ||
!apds.readRedLight(red_light) ||
!apds.readGreenLight(green_light) ||
!apds.readBlueLight(blue_light) ) {
Serial.println("Error reading light values");
} else {
Serial.print("Ambient: ");
Serial.print(ambient_light);
Serial.print(" Red: ");
Serial.print(red_light);
Serial.print(" Green: ");
Serial.print(green_light);
Serial.print(" Blue: ");
Serial.println(blue_light);
}
// Wait 1 second before next reading
delay(1000);
}
@@ -0,0 +1,128 @@
/****************************************************************
GestureTest.ino
APDS-9960 RGB and Gesture Sensor
Shawn Hymel @ SparkFun Electronics
May 30, 2014
https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
Tests the gesture sensing abilities of the APDS-9960. Configures
APDS-9960 over I2C and waits for gesture events. Calculates the
direction of the swipe (up, down, left, right) and displays it
on a serial console.
To perform a NEAR gesture, hold your hand
far above the sensor and move it close to the sensor (within 2
inches). Hold your hand there for at least 1 second and move it
away.
To perform a FAR gesture, hold your hand within 2 inches of the
sensor for at least 1 second and then move it above (out of
range) of the sensor.
Hardware Connections:
IMPORTANT: The APDS-9960 can only accept 3.3V!
Arduino Pin APDS-9960 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
2 INT Interrupt
Resources:
Include Wire.h and SparkFun_APDS-9960.h
Development environment specifics:
Written in Arduino 1.0.5
Tested with SparkFun Arduino Pro Mini 3.3V
This code is beerware; if you see me (or any other SparkFun
employee) at the local, and you've found our code helpful, please
buy us a round!
Distributed as-is; no warranty is given.
****************************************************************/
#include <Wire.h>
#include <SparkFun_APDS9960.h>
// Pins
#define APDS9960_INT 2 // Needs to be an interrupt pin
// Constants
// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
int isr_flag = 0;
void setup() {
// Set interrupt pin as input
pinMode(APDS9960_INT, INPUT);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("--------------------------------"));
Serial.println(F("SparkFun APDS-9960 - GestureTest"));
Serial.println(F("--------------------------------"));
// Initialize interrupt service routine
attachInterrupt(0, interruptRoutine, FALLING);
// Initialize APDS-9960 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9960 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9960 init!"));
}
// Start running the APDS-9960 gesture sensor engine
if ( apds.enableGestureSensor(true) ) {
Serial.println(F("Gesture sensor is now running"));
} else {
Serial.println(F("Something went wrong during gesture sensor init!"));
}
}
void loop() {
if( isr_flag == 1 ) {
detachInterrupt(0);
handleGesture();
isr_flag = 0;
attachInterrupt(0, interruptRoutine, FALLING);
}
}
void interruptRoutine() {
isr_flag = 1;
}
void handleGesture() {
if ( apds.isGestureAvailable() ) {
switch ( apds.readGesture() ) {
case DIR_UP:
Serial.println("UP");
break;
case DIR_DOWN:
Serial.println("DOWN");
break;
case DIR_LEFT:
Serial.println("LEFT");
break;
case DIR_RIGHT:
Serial.println("RIGHT");
break;
case DIR_NEAR:
Serial.println("NEAR");
break;
case DIR_FAR:
Serial.println("FAR");
break;
default:
Serial.println("NONE");
}
}
}
@@ -0,0 +1,129 @@
/****************************************************************
ProximityInterrupt.ino
APDS-9960 RGB and Gesture Sensor
Shawn Hymel @ SparkFun Electronics
October 24, 2014
https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
Tests the proximity interrupt abilities of the APDS-9960.
Configures the APDS-9960 over I2C and waits for an external
interrupt based on high or low proximity conditions. Move your
hand near the sensor and watch the LED on pin 13.
Hardware Connections:
IMPORTANT: The APDS-9960 can only accept 3.3V!
Arduino Pin APDS-9960 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
2 INT Interrupt
13 - LED
Resources:
Include Wire.h and SparkFun_APDS-9960.h
Development environment specifics:
Written in Arduino 1.0.5
Tested with SparkFun Arduino Pro Mini 3.3V
This code is beerware; if you see me (or any other SparkFun
employee) at the local, and you've found our code helpful, please
buy us a round!
Distributed as-is; no warranty is given.
****************************************************************/
#include <Wire.h>
#include <SparkFun_APDS9960.h>
// Pins
#define APDS9960_INT 2 // Needs to be an interrupt pin
#define LED_PIN 13 // LED for showing interrupt
// Constants
#define PROX_INT_HIGH 50 // Proximity level for interrupt
#define PROX_INT_LOW 0 // No far interrupt
// Global variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
uint8_t proximity_data = 0;
int isr_flag = 0;
void setup() {
// Set LED as output
pinMode(LED_PIN, OUTPUT);
pinMode(APDS9960_INT, INPUT);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("---------------------------------------"));
Serial.println(F("SparkFun APDS-9960 - ProximityInterrupt"));
Serial.println(F("---------------------------------------"));
// Initialize interrupt service routine
attachInterrupt(0, interruptRoutine, FALLING);
// Initialize APDS-9960 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9960 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9960 init!"));
}
// Adjust the Proximity sensor gain
if ( !apds.setProximityGain(PGAIN_2X) ) {
Serial.println(F("Something went wrong trying to set PGAIN"));
}
// Set proximity interrupt thresholds
if ( !apds.setProximityIntLowThreshold(PROX_INT_LOW) ) {
Serial.println(F("Error writing low threshold"));
}
if ( !apds.setProximityIntHighThreshold(PROX_INT_HIGH) ) {
Serial.println(F("Error writing high threshold"));
}
// Start running the APDS-9960 proximity sensor (interrupts)
if ( apds.enableProximitySensor(true) ) {
Serial.println(F("Proximity sensor is now running"));
} else {
Serial.println(F("Something went wrong during sensor init!"));
}
}
void loop() {
// If interrupt occurs, print out the proximity level
if ( isr_flag == 1 ) {
// Read proximity level and print it out
if ( !apds.readProximity(proximity_data) ) {
Serial.println("Error reading proximity value");
} else {
Serial.print("Proximity detected! Level: ");
Serial.println(proximity_data);
}
// Turn on LED for a half a second
digitalWrite(LED_PIN, HIGH);
delay(500);
digitalWrite(LED_PIN, LOW);
// Reset flag and clear APDS-9960 interrupt (IMPORTANT!)
isr_flag = 0;
if ( !apds.clearProximityInt() ) {
Serial.println("Error clearing interrupt");
}
}
}
void interruptRoutine() {
isr_flag = 1;
}
@@ -0,0 +1,85 @@
/****************************************************************
ProximityTest.ino
APDS-9960 RGB and Gesture Sensor
Shawn Hymel @ SparkFun Electronics
October 28, 2014
https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
Tests the proximity sensing abilities of the APDS-9960.
Configures the APDS-9960 over I2C and polls for the distance to
the object nearest the sensor.
Hardware Connections:
IMPORTANT: The APDS-9960 can only accept 3.3V!
Arduino Pin APDS-9960 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
Resources:
Include Wire.h and SparkFun_APDS-9960.h
Development environment specifics:
Written in Arduino 1.0.5
Tested with SparkFun Arduino Pro Mini 3.3V
This code is beerware; if you see me (or any other SparkFun
employee) at the local, and you've found our code helpful, please
buy us a round!
Distributed as-is; no warranty is given.
****************************************************************/
#include <Wire.h>
#include <SparkFun_APDS9960.h>
// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
uint8_t proximity_data = 0;
void setup() {
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("------------------------------------"));
Serial.println(F("SparkFun APDS-9960 - ProximitySensor"));
Serial.println(F("------------------------------------"));
// Initialize APDS-9960 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9960 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9960 init!"));
}
// Adjust the Proximity sensor gain
if ( !apds.setProximityGain(PGAIN_2X) ) {
Serial.println(F("Something went wrong trying to set PGAIN"));
}
// Start running the APDS-9960 proximity sensor (no interrupts)
if ( apds.enableProximitySensor(false) ) {
Serial.println(F("Proximity sensor is now running"));
} else {
Serial.println(F("Something went wrong during sensor init!"));
}
}
void loop() {
// Read the proximity value
if ( !apds.readProximity(proximity_data) ) {
Serial.println("Error reading proximity value");
} else {
Serial.print("Proximity: ");
Serial.println(proximity_data);
}
// Wait 250 ms before next reading
delay(250);
}
@@ -0,0 +1,9 @@
name=SparkFun APDS9960 RGB and Gesture Sensor
version=1.4.2
author=SparkFun Electronics <techsupport@sparkfun.com>
maintainer=SparkFun Electronics <sparkfun.com>
sentence=Library for the Avago APDS-9960 sensor
paragraph=This library works with the SparkFun Breakout board for the Avago APDS-9960 proximity, light, RGB, and gesture sensor, made by SparkFun Electronics.
category=Sensors
url=https://github.com/sparkfun/SparkFun_APDS-9960_Sensor_Arduino_Library
architectures=*
@@ -0,0 +1,5 @@
This folder should contain the .cpp and .h files for the library.
If backward compatibility is needed, source code should be placed in the library root folder and in a "utilyt" folder.
Check out the [library specification](https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification) for more details.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,349 @@
/**
* @file SparkFun_APDS-9960.h
* @brief Library for the SparkFun APDS-9960 breakout board
* @author Shawn Hymel (SparkFun Electronics)
*
* @copyright This code is public domain but you buy me a beer if you use
* this and we meet someday (Beerware license).
*
* This library interfaces the Avago APDS-9960 to Arduino over I2C. The library
* relies on the Arduino Wire (I2C) library. to use the library, instantiate an
* APDS9960 object, call init(), and call the appropriate functions.
*/
#ifndef SparkFun_APDS9960_H
#define SparkFun_APDS9960_H
#include <Arduino.h>
/* Debug */
#define DEBUG 0
/* APDS-9960 I2C address */
#define APDS9960_I2C_ADDR 0x39
/* Gesture parameters */
#define GESTURE_THRESHOLD_OUT 10
#define GESTURE_SENSITIVITY_1 50
#define GESTURE_SENSITIVITY_2 20
/* Error code for returned values */
#define ERROR 0xFF
/* Acceptable device IDs */
#define APDS9960_ID_1 0xAB
#define APDS9960_ID_2 0x9C
/* Misc parameters */
#define FIFO_PAUSE_TIME 30 // Wait period (ms) between FIFO reads
/* APDS-9960 register addresses */
#define APDS9960_ENABLE 0x80
#define APDS9960_ATIME 0x81
#define APDS9960_WTIME 0x83
#define APDS9960_AILTL 0x84
#define APDS9960_AILTH 0x85
#define APDS9960_AIHTL 0x86
#define APDS9960_AIHTH 0x87
#define APDS9960_PILT 0x89
#define APDS9960_PIHT 0x8B
#define APDS9960_PERS 0x8C
#define APDS9960_CONFIG1 0x8D
#define APDS9960_PPULSE 0x8E
#define APDS9960_CONTROL 0x8F
#define APDS9960_CONFIG2 0x90
#define APDS9960_ID 0x92
#define APDS9960_STATUS 0x93
#define APDS9960_CDATAL 0x94
#define APDS9960_CDATAH 0x95
#define APDS9960_RDATAL 0x96
#define APDS9960_RDATAH 0x97
#define APDS9960_GDATAL 0x98
#define APDS9960_GDATAH 0x99
#define APDS9960_BDATAL 0x9A
#define APDS9960_BDATAH 0x9B
#define APDS9960_PDATA 0x9C
#define APDS9960_POFFSET_UR 0x9D
#define APDS9960_POFFSET_DL 0x9E
#define APDS9960_CONFIG3 0x9F
#define APDS9960_GPENTH 0xA0
#define APDS9960_GEXTH 0xA1
#define APDS9960_GCONF1 0xA2
#define APDS9960_GCONF2 0xA3
#define APDS9960_GOFFSET_U 0xA4
#define APDS9960_GOFFSET_D 0xA5
#define APDS9960_GOFFSET_L 0xA7
#define APDS9960_GOFFSET_R 0xA9
#define APDS9960_GPULSE 0xA6
#define APDS9960_GCONF3 0xAA
#define APDS9960_GCONF4 0xAB
#define APDS9960_GFLVL 0xAE
#define APDS9960_GSTATUS 0xAF
#define APDS9960_IFORCE 0xE4
#define APDS9960_PICLEAR 0xE5
#define APDS9960_CICLEAR 0xE6
#define APDS9960_AICLEAR 0xE7
#define APDS9960_GFIFO_U 0xFC
#define APDS9960_GFIFO_D 0xFD
#define APDS9960_GFIFO_L 0xFE
#define APDS9960_GFIFO_R 0xFF
/* Bit fields */
#define APDS9960_PON 0b00000001
#define APDS9960_AEN 0b00000010
#define APDS9960_PEN 0b00000100
#define APDS9960_WEN 0b00001000
#define APSD9960_AIEN 0b00010000
#define APDS9960_PIEN 0b00100000
#define APDS9960_GEN 0b01000000
#define APDS9960_GVALID 0b00000001
/* On/Off definitions */
#define OFF 0
#define ON 1
/* Acceptable parameters for setMode */
#define POWER 0
#define AMBIENT_LIGHT 1
#define PROXIMITY 2
#define WAIT 3
#define AMBIENT_LIGHT_INT 4
#define PROXIMITY_INT 5
#define GESTURE 6
#define ALL 7
/* LED Drive values */
#define LED_DRIVE_100MA 0
#define LED_DRIVE_50MA 1
#define LED_DRIVE_25MA 2
#define LED_DRIVE_12_5MA 3
/* Proximity Gain (PGAIN) values */
#define PGAIN_1X 0
#define PGAIN_2X 1
#define PGAIN_4X 2
#define PGAIN_8X 3
/* ALS Gain (AGAIN) values */
#define AGAIN_1X 0
#define AGAIN_4X 1
#define AGAIN_16X 2
#define AGAIN_64X 3
/* Gesture Gain (GGAIN) values */
#define GGAIN_1X 0
#define GGAIN_2X 1
#define GGAIN_4X 2
#define GGAIN_8X 3
/* LED Boost values */
#define LED_BOOST_100 0
#define LED_BOOST_150 1
#define LED_BOOST_200 2
#define LED_BOOST_300 3
/* Gesture wait time values */
#define GWTIME_0MS 0
#define GWTIME_2_8MS 1
#define GWTIME_5_6MS 2
#define GWTIME_8_4MS 3
#define GWTIME_14_0MS 4
#define GWTIME_22_4MS 5
#define GWTIME_30_8MS 6
#define GWTIME_39_2MS 7
/* Default values */
#define DEFAULT_ATIME 219 // 103ms
#define DEFAULT_WTIME 246 // 27ms
#define DEFAULT_PROX_PPULSE 0x87 // 16us, 8 pulses
#define DEFAULT_GESTURE_PPULSE 0x89 // 16us, 10 pulses
#define DEFAULT_POFFSET_UR 0 // 0 offset
#define DEFAULT_POFFSET_DL 0 // 0 offset
#define DEFAULT_CONFIG1 0x60 // No 12x wait (WTIME) factor
#define DEFAULT_LDRIVE LED_DRIVE_100MA
#define DEFAULT_PGAIN PGAIN_4X
#define DEFAULT_AGAIN AGAIN_4X
#define DEFAULT_PILT 0 // Low proximity threshold
#define DEFAULT_PIHT 50 // High proximity threshold
#define DEFAULT_AILT 0xFFFF // Force interrupt for calibration
#define DEFAULT_AIHT 0
#define DEFAULT_PERS 0x11 // 2 consecutive prox or ALS for int.
#define DEFAULT_CONFIG2 0x01 // No saturation interrupts or LED boost
#define DEFAULT_CONFIG3 0 // Enable all photodiodes, no SAI
#define DEFAULT_GPENTH 40 // Threshold for entering gesture mode
#define DEFAULT_GEXTH 30 // Threshold for exiting gesture mode
#define DEFAULT_GCONF1 0x40 // 4 gesture events for int., 1 for exit
#define DEFAULT_GGAIN GGAIN_4X
#define DEFAULT_GLDRIVE LED_DRIVE_100MA
#define DEFAULT_GWTIME GWTIME_2_8MS
#define DEFAULT_GOFFSET 0 // No offset scaling for gesture mode
#define DEFAULT_GPULSE 0xC9 // 32us, 10 pulses
#define DEFAULT_GCONF3 0 // All photodiodes active during gesture
#define DEFAULT_GIEN 0 // Disable gesture interrupts
/* Direction definitions */
enum {
DIR_NONE,
DIR_LEFT,
DIR_RIGHT,
DIR_UP,
DIR_DOWN,
DIR_NEAR,
DIR_FAR,
DIR_ALL
};
/* State definitions */
enum {
N_A_STATE, // NA_STATE - collision with ESP8266WiFi.h
NEAR_STATE,
FAR_STATE,
ALL_STATE
};
/* Container for gesture data */
typedef struct gesture_data_type {
uint8_t u_data[32];
uint8_t d_data[32];
uint8_t l_data[32];
uint8_t r_data[32];
uint8_t index;
uint8_t total_gestures;
uint8_t in_threshold;
uint8_t out_threshold;
} gesture_data_type;
/* APDS9960 Class */
class SparkFun_APDS9960 {
public:
/* Initialization methods */
SparkFun_APDS9960();
~SparkFun_APDS9960();
bool init();
uint8_t getMode();
bool setMode(uint8_t mode, uint8_t enable);
/* Turn the APDS-9960 on and off */
bool enablePower();
bool disablePower();
/* Enable or disable specific sensors */
bool enableLightSensor(bool interrupts = false);
bool disableLightSensor();
bool enableProximitySensor(bool interrupts = false);
bool disableProximitySensor();
bool enableGestureSensor(bool interrupts = true);
bool disableGestureSensor();
/* LED drive strength control */
uint8_t getLEDDrive();
bool setLEDDrive(uint8_t drive);
uint8_t getGestureLEDDrive();
bool setGestureLEDDrive(uint8_t drive);
/* Gain control */
uint8_t getAmbientLightGain();
bool setAmbientLightGain(uint8_t gain);
uint8_t getProximityGain();
bool setProximityGain(uint8_t gain);
uint8_t getGestureGain();
bool setGestureGain(uint8_t gain);
/* Get and set light interrupt thresholds */
bool getLightIntLowThreshold(uint16_t &threshold);
bool setLightIntLowThreshold(uint16_t threshold);
bool getLightIntHighThreshold(uint16_t &threshold);
bool setLightIntHighThreshold(uint16_t threshold);
/* Get and set proximity interrupt thresholds */
bool getProximityIntLowThreshold(uint8_t &threshold);
bool setProximityIntLowThreshold(uint8_t threshold);
bool getProximityIntHighThreshold(uint8_t &threshold);
bool setProximityIntHighThreshold(uint8_t threshold);
/* Get and set interrupt enables */
uint8_t getAmbientLightIntEnable();
bool setAmbientLightIntEnable(uint8_t enable);
uint8_t getProximityIntEnable();
bool setProximityIntEnable(uint8_t enable);
uint8_t getGestureIntEnable();
bool setGestureIntEnable(uint8_t enable);
/* Clear interrupts */
bool clearAmbientLightInt();
bool clearProximityInt();
/* Ambient light methods */
bool readAmbientLight(uint16_t &val);
bool readRedLight(uint16_t &val);
bool readGreenLight(uint16_t &val);
bool readBlueLight(uint16_t &val);
/* Proximity methods */
bool readProximity(uint8_t &val);
/* Gesture methods */
bool isGestureAvailable();
int readGesture();
int readGestureNonBlocking();
private:
/* Gesture processing */
void resetGestureParameters();
bool processGestureData();
bool decodeGesture();
/* Proximity Interrupt Threshold */
uint8_t getProxIntLowThresh();
bool setProxIntLowThresh(uint8_t threshold);
uint8_t getProxIntHighThresh();
bool setProxIntHighThresh(uint8_t threshold);
/* LED Boost Control */
uint8_t getLEDBoost();
bool setLEDBoost(uint8_t boost);
/* Proximity photodiode select */
uint8_t getProxGainCompEnable();
bool setProxGainCompEnable(uint8_t enable);
uint8_t getProxPhotoMask();
bool setProxPhotoMask(uint8_t mask);
/* Gesture threshold control */
uint8_t getGestureEnterThresh();
bool setGestureEnterThresh(uint8_t threshold);
uint8_t getGestureExitThresh();
bool setGestureExitThresh(uint8_t threshold);
/* Gesture LED, gain, and time control */
uint8_t getGestureWaitTime();
bool setGestureWaitTime(uint8_t time);
/* Gesture mode */
uint8_t getGestureMode();
bool setGestureMode(uint8_t mode);
/* Raw I2C Commands */
bool wireWriteByte(uint8_t val);
bool wireWriteDataByte(uint8_t reg, uint8_t val);
bool wireWriteDataBlock(uint8_t reg, uint8_t *val, unsigned int len);
bool wireReadDataByte(uint8_t reg, uint8_t &val);
int wireReadDataBlock(uint8_t reg, uint8_t *val, unsigned int len);
/* Members */
gesture_data_type gesture_data_;
int gesture_ud_delta_;
int gesture_lr_delta_;
int gesture_ud_count_;
int gesture_lr_count_;
int gesture_near_count_;
int gesture_far_count_;
int gesture_state_;
int gesture_motion_;
};
#endif
+1 -1
View File
@@ -23,7 +23,7 @@
// MQTT_MAX_PACKET_SIZE : Maximum packet size
#ifndef MQTT_MAX_PACKET_SIZE
#define MQTT_MAX_PACKET_SIZE 256 // need to fix this here, because this define cannot be overruled within the Arduino sketch...
#define MQTT_MAX_PACKET_SIZE 384 // need to fix this here, because this define cannot be overruled within the Arduino sketch...
#endif
// MQTT_KEEPALIVE : keepAlive interval in Seconds
+36 -13
View File
@@ -122,17 +122,6 @@ try:
objectDumpBin = sys.argv[1]
output_format="{:<30}|{:<11}|{:<11}|{:<11}|{:<11}|{:<11}"
print(output_format.format(
"plugin",
"cache IRAM",
"init RAM",
"r.o. RAM",
"uninit RAM",
"Flash ROM",
))
enable_all()
@@ -152,6 +141,7 @@ try:
test_plugins=plugins
test_plugins.sort()
print("Analysing ESPEasy memory usage for env {} ...\n".format(env))
#### disable all plugins and to get base size
for plugin in test_plugins:
@@ -161,7 +151,7 @@ try:
# for lib in libs:
# disable_lib(lib)
#build without plugins to get base memory usage
#just build the core without plugins to get base memory usage
subprocess.check_call("platformio run --silent --environment "+env, shell=True)
# #two times, sometimes it changes a few bytes somehow
# SEEMS TO BE NOT USEFULL
@@ -169,6 +159,27 @@ try:
base=analyse_memory(".pioenvs/"+env+"/firmware.elf")
output_format="{:<30}|{:<11}|{:<11}|{:<11}|{:<11}|{:<11}"
print(output_format.format(
"module",
"cache IRAM",
"init RAM",
"r.o. RAM",
"uninit RAM",
"Flash ROM",
))
print(output_format.format(
"CORE",
base['text'],
base['data'],
base['rodata'],
base['bss'],
base['irom0_text'],
))
# note: unused libs never use any memory, so dont have to test this
# ##### test per lib
# results={}
@@ -218,13 +229,23 @@ try:
total=analyse_memory(".pioenvs/"+env+"/firmware.elf")
print(output_format.format(
"ALL",
"ALL PLUGINS",
total['text']-base['text'],
total['data']-base['data'],
total['rodata']-base['rodata'],
total['bss']-base['bss'],
total['irom0_text']-base['irom0_text'],
))
print(output_format.format(
"ESPEasy",
total['text'],
total['data'],
total['rodata'],
total['bss'],
total['irom0_text'],
))
except:
enable_all()
@@ -232,3 +253,5 @@ except:
enable_all()
print("\n")
+50 -11
View File
@@ -86,12 +86,7 @@ void ExecuteCommand(byte source, const char *Line)
if (strcasecmp_P(Command, PSTR("clearRTCRAM")) == 0)
{
success = true;
RTC.factoryResetCounter = 0;
RTC.deepSleepState = 0;
RTC.rebootCounter = 0;
RTC.flashDayCounter = 0;
RTC.flashCounter = 0;
saveToRTC();
initRTC();
}
if (strcasecmp_P(Command, PSTR("notify")) == 0)
@@ -154,7 +149,7 @@ void ExecuteCommand(byte source, const char *Line)
{
Serial.print(lowestRAM);
Serial.print(F(" : "));
Serial.println(lowestRAMid);
Serial.println(lowestRAMfunction);
success = true;
}
@@ -268,7 +263,7 @@ void ExecuteCommand(byte source, const char *Line)
{
success = true;
if (Par1 > 0)
deepSleep(Par1);
deepSleepStart(Par1); // call the second part of the function to avoid check and enable one-shot operation
}
if (strcasecmp_P(Command, PSTR("TaskValueSet")) == 0)
@@ -290,7 +285,7 @@ void ExecuteCommand(byte source, const char *Line)
if (strcasecmp_P(Command, PSTR("TimerSet")) == 0)
{
if (Par1>=0 && Par1<RULES_TIMER_MAX)
if (Par1>=1 && Par1<=RULES_TIMER_MAX)
{
success = true;
if (Par2)
@@ -300,12 +295,16 @@ void ExecuteCommand(byte source, const char *Line)
//disable existing timer
RulesTimer[Par1 - 1] = 0L;
}
else
{
addLog(LOG_LEVEL_ERROR, F("TIMER: invalid timer number"));
}
}
if (strcasecmp_P(Command, PSTR("Delay")) == 0)
{
success = true;
delayMillis(Par1);
delayBackground(Par1);
}
if (strcasecmp_P(Command, PSTR("Rules")) == 0)
@@ -420,6 +419,18 @@ void ExecuteCommand(byte source, const char *Line)
strcpy(SecuritySettings.WifiKey, Line + 8);
}
if (strcasecmp_P(Command, PSTR("WifiSSID2")) == 0)
{
success = true;
strcpy(SecuritySettings.WifiSSID2, Line + 10);
}
if (strcasecmp_P(Command, PSTR("WifiKey2")) == 0)
{
success = true;
strcpy(SecuritySettings.WifiKey2, Line + 9);
}
if (strcasecmp_P(Command, PSTR("WifiScan")) == 0)
{
success = true;
@@ -429,7 +440,7 @@ void ExecuteCommand(byte source, const char *Line)
if (strcasecmp_P(Command, PSTR("WifiConnect")) == 0)
{
success = true;
WifiConnect(true, 1);
WifiConnect(1);
}
if (strcasecmp_P(Command, PSTR("WifiDisconnect")) == 0)
@@ -438,6 +449,31 @@ void ExecuteCommand(byte source, const char *Line)
WifiDisconnect();
}
if (strcasecmp_P(Command, PSTR("WifiAPMode")) == 0)
{
WifiAPMode(true);
success = true;
}
if (strcasecmp_P(Command, PSTR("Unit")) == 0)
{
success = true;
Settings.Unit=Par1;
}
if (strcasecmp_P(Command, PSTR("Name")) == 0)
{
success = true;
strcpy(Settings.Name, Line + 5);
}
if (strcasecmp_P(Command, PSTR("Password")) == 0)
{
success = true;
strcpy(SecuritySettings.Password, Line + 9);
}
if (strcasecmp_P(Command, PSTR("Reboot")) == 0)
{
success = true;
@@ -503,9 +539,12 @@ void ExecuteCommand(byte source, const char *Line)
sprintf_P(str, PSTR("%u.%u.%u.%u"), ip[0], ip[1], ip[2], ip[3]);
Serial.print(F(" IP Address : ")); Serial.println(str);
Serial.print(F(" Build : ")); Serial.println((int)BUILD);
Serial.print(F(" Name : ")); Serial.println(Settings.Name);
Serial.print(F(" Unit : ")); Serial.println((int)Settings.Unit);
Serial.print(F(" WifiSSID : ")); Serial.println(SecuritySettings.WifiSSID);
Serial.print(F(" WifiKey : ")); Serial.println(SecuritySettings.WifiKey);
Serial.print(F(" WifiSSID2 : ")); Serial.println(SecuritySettings.WifiSSID2);
Serial.print(F(" WifiKey2 : ")); Serial.println(SecuritySettings.WifiKey2);
Serial.print(F(" Free mem : ")); Serial.println(FreeMem());
}
+14 -7
View File
@@ -10,6 +10,9 @@ boolean sendData(struct EventStruct *event)
if (Settings.GlobalSync && Settings.TaskDeviceGlobalSync[event->TaskIndex])
SendUDPTaskData(0, event->TaskIndex, event->TaskIndex);
if (Settings.UseValueLogger && Settings.InitSPI && Settings.Pin_sd_cs >= 0)
SendValueLogger(event->TaskIndex);
// if (!Settings.TaskDeviceSendData[event->TaskIndex])
// return false;
@@ -19,12 +22,13 @@ boolean sendData(struct EventStruct *event)
if (dif < Settings.MessageDelay)
{
uint16_t delayms = Settings.MessageDelay - dif;
// char log[30];
// sprintf_P(log, PSTR("CTRL : Message delay %u ms"), delayms);
addLog(LOG_LEVEL_DEBUG_MORE, String(F("CTRL : Message delay (ms): "))+delayms);
unsigned long timer = millis() + delayms;
while (millis() < timer)
backgroundtasks();
//this is logged nowhere else, so might as well disable it here also:
// addLog(LOG_LEVEL_DEBUG_MORE, String(F("CTRL : Message delay (ms): "))+delayms);
delayBackground(delayms);
// unsigned long timer = millis() + delayms;
// while (millis() < timer)
// backgroundtasks();
}
}
@@ -53,7 +57,7 @@ boolean sendData(struct EventStruct *event)
// handle MQTT messages
void callback(char* c_topic, byte* b_payload, unsigned int length) {
// char log[256];
char c_payload[256];
char c_payload[384];
statusLED(true);
@@ -129,6 +133,9 @@ void MQTTConnect()
log = F("Subscribed to: ");
log += subscribeTo;
addLog(LOG_LEVEL_INFO, log);
MQTTclient.publish(LWTTopic.c_str(), "Connected");
statusLED(true);
break; // end loop if succesfull
}
+133 -70
View File
@@ -73,11 +73,9 @@
// You can always change these during runtime and save to eeprom
// After loading firmware, issue a 'reset' command to load the defaults.
#define DEFAULT_NAME "newdevice" // Enter your device friendly name
#define DEFAULT_NAME "ESP_Easy" // Enter your device friendly name
#define DEFAULT_SSID "ssid" // Enter your network SSID
#define DEFAULT_KEY "wpakey" // Enter your network WPA key
#define DEFAULT_SERVER "192.168.0.8" // Enter your Domoticz Server IP address
#define DEFAULT_PORT 8080 // Enter your Domoticz Server port value
#define DEFAULT_DELAY 60 // Enter your Send delay in seconds
#define DEFAULT_AP_KEY "configesp" // Enter network WPA key for AP (config) mode
@@ -87,9 +85,12 @@
#define DEFAULT_GW "192.168.0.1" // Enter your gateway
#define DEFAULT_SUBNET "255.255.255.0" // Enter your subnet
#define DEFAULT_MQTT_TEMPLATE false // true or false enabled or disabled set mqqt sub and pub
#define DEFAULT_MQTT_PUB "sensors/espeasy/%sysname%/%tskname%/%valname%" // Enter your pub
#define DEFAULT_MQTT_SUB "sensors/espeasy/%sysname%/#" // Enter your sub
#define DEFAULT_CONTROLLER false // true or false enabled or disabled, set 1st controller defaults
// using a default template, you also need to set a DEFAULT PROTOCOL to a suitable MQTT protocol !
#define DEFAULT_PUB "sensors/espeasy/%sysname%/%tskname%/%valname%" // Enter your pub
#define DEFAULT_SUB "sensors/espeasy/%sysname%/#" // Enter your sub
#define DEFAULT_SERVER "192.168.0.8" // Enter your Server IP address
#define DEFAULT_PORT 8080 // Enter your Server port value
#define DEFAULT_PROTOCOL 1 // Protocol used for controller communications
// 1 = Domoticz HTTP
@@ -114,6 +115,9 @@
//Note: This adds around 10kb to the firmware size, and 1kb extra ram.
// #define FEATURE_ARDUINO_OTA
//enable mDNS mode (adds about 6kb ram and some bytes IRAM)
// #define FEATURE_MDNS
//enable reporting status to ESPEasy developers.
//this informs us of crashes and stability issues.
@@ -201,12 +205,16 @@
#define CMD_REBOOT 89
#define CMD_WIFI_DISCONNECT 135
#define DEVICES_MAX 64
#if defined(PLUGIN_BUILD_TESTING) || defined(PLUGIN_BUILD_DEV)
#define DEVICES_MAX 72
#else
#define DEVICES_MAX 64
#endif
#define TASKS_MAX 12 // max 12!
#define CONTROLLER_MAX 3 // max 4!
#define NOTIFICATION_MAX 3 // max 4!
#define VARS_PER_TASK 4
#define PLUGIN_MAX 64
#define PLUGIN_MAX DEVICES_MAX
#define PLUGIN_CONFIGVAR_MAX 8
#define PLUGIN_CONFIGFLOATVAR_MAX 4
#define PLUGIN_CONFIGLONGVAR_MAX 4
@@ -263,17 +271,23 @@
#define DAT_TASKS_SIZE 2048
#define DAT_TASKS_CUSTOM_OFFSET 1024
#define DAT_CUSTOM_CONTROLLER_SIZE 1024
#define DAT_CONTROLLER_SIZE 1024
#define DAT_NOTIFICATION_SIZE 1024
#define DAT_OFFSET_TASKS 4096 // each task = 2k, (1024 basic + 1024 bytes custom), 12 max
#define DAT_OFFSET_CONTROLLER 28672 // each controller = 1k, 4 max
#define DAT_OFFSET_CUSTOMCONTROLLER 32768 // custom controller config = 4k, currently only one can use it.
#define DAT_OFFSET_CUSTOM_CONTROLLER 32768 // each custom controller config = 1k, 4 max.
#include "lwip/tcp_impl.h"
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <WiFiUdp.h>
#include <ESP8266WebServer.h>
#ifdef FEATURE_MDNS
#include <ESP8266mDNS.h>
#endif
#include <Wire.h>
#include <SPI.h>
#include <PubSubClient.h>
@@ -296,6 +310,7 @@ ADC_MODE(ADC_VCC);
#include "lwip/udp.h"
#include "lwip/igmp.h"
#include "include/UdpContext.h"
#include "limits.h"
extern "C" {
#include "user_interface.h"
@@ -313,7 +328,9 @@ bool ArduinoOTAtriggered=false;
const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 4, 1);
DNSServer dnsServer;
#ifdef FEATURE_MDNS
MDNSResponder mdns;
#endif
// MQTT client
WiFiClient mqtt;
@@ -322,7 +339,7 @@ PubSubClient MQTTclient(mqtt);
// WebServer
ESP8266WebServer WebServer(80);
// syslog stuff
// udp protocol stuff (syslog, global sync, node info list, ntp time)
WiFiUDP portUDP;
@@ -345,6 +362,7 @@ struct SecurityStruct
char ControllerUser[CONTROLLER_MAX][26];
char ControllerPassword[CONTROLLER_MAX][64];
char Password[26];
//its safe to extend this struct, up to 512 bytes, default values in config are 0
} SecuritySettings;
struct SettingsStruct
@@ -415,6 +433,10 @@ struct SettingsStruct
boolean NotificationEnabled[NOTIFICATION_MAX];
unsigned int TaskDeviceID[CONTROLLER_MAX][TASKS_MAX];
boolean TaskDeviceSendData[CONTROLLER_MAX][TASKS_MAX];
boolean Pin_status_led_Inversed;
boolean deepSleepOnFail;
boolean UseValueLogger;
//its safe to extend this struct, up to 65535 bytes, default values in config are 0
} Settings;
struct ControllerSettingsStruct
@@ -438,6 +460,7 @@ struct NotificationSettingsStruct
char Body[513];
byte Pin1;
byte Pin2;
//its safe to extend this struct, up to 4096 bytes, default values in config are 0
};
struct ExtraTaskSettingsStruct
@@ -465,6 +488,8 @@ struct EventStruct
int Par1;
int Par2;
int Par3;
int Par4;
int Par5;
byte OriginTaskIndex;
String String1;
String String2;
@@ -546,18 +571,26 @@ struct pinStatesStruct
uint16_t value;
} pinStates[PINSTATE_TABLE_MAX];
// this offsets are in blocks, bytes = blocks * 4
#define RTC_BASE_STRUCT 64
#define RTC_BASE_USERVAR 74
//max 40 bytes: ( 74 - 64 ) * 4
struct RTCStruct
{
byte ID1;
byte ID2;
boolean valid;
boolean unused1;
byte factoryResetCounter;
byte deepSleepState;
byte rebootCounter; //not used yet?
byte unused2;
byte flashDayCounter;
unsigned long flashCounter;
unsigned long bootCounter;
} RTC;
int deviceCount = -1;
int protocolCount = -1;
int notificationCount = -1;
@@ -577,10 +610,10 @@ unsigned long timerwd;
unsigned long lastSend;
unsigned int NC_Count = 0;
unsigned int C_Count = 0;
boolean AP_Mode = false;
byte cmd_within_mainloop = 0;
unsigned long connectionFailures;
unsigned long wdcounter = 0;
unsigned long timerAPoff = 0;
#if FEATURE_ADC_VCC
float vcc = -1.0;
@@ -616,24 +649,14 @@ unsigned long dailyResetCounter = 0;
String eventBuffer = "";
uint16_t lowestRAM = 0;
byte lowestRAMid=0;
/*
1 savetoflash - obsolete
2 loadfrom flash - obsolete
3 zerofillflash - obsolete
4 rulesprocessing
5 handle_download
6 handle_css
7 handlefileupload
8 handle_rules
9 handle_devices
*/
String lowestRAMfunction = "";
/*********************************************************************************************\
* SETUP
\*********************************************************************************************/
void setup()
{
lowestRAM = FreeMem();
Serial.begin(115200);
@@ -655,6 +678,43 @@ void setup()
log += BUILD_GIT;
addLog(LOG_LEVEL_INFO, log);
//warm boot
if (readFromRTC())
{
RTC.bootCounter++;
readUserVarFromRTC();
if (RTC.deepSleepState == 1)
{
log = F("INIT : Rebooted from deepsleep #");
lastBootCause=BOOT_CAUSE_DEEP_SLEEP;
}
else
log = F("INIT : Warm boot #");
log += RTC.bootCounter;
}
//cold boot (RTC memory empty)
else
{
initRTC();
// cold boot situation
if (lastBootCause == BOOT_CAUSE_MANUAL_REBOOT) // only set this if not set earlier during boot stage.
lastBootCause = BOOT_CAUSE_COLD_BOOT;
log = F("INIT : Cold Boot");
}
RTC.deepSleepState=0;
saveToRTC();
addLog(LOG_LEVEL_INFO, log);
fileSystemCheck();
LoadSettings();
@@ -695,8 +755,22 @@ void setup()
WiFi.persistent(false); // Do not use SDK storage of SSID/WPA parameters
WifiAPconfig();
if (!WifiConnect(true,3))
WifiConnect(false,3);
if (Settings.deepSleep)
{
//only one attempt in deepsleep, to conserve battery
if (!WifiConnect(1))
{
if (Settings.deepSleepOnFail)
{
addLog(LOG_LEVEL_ERROR, F("SLEEP: Connection failed, going back to sleep."));
deepSleep(Settings.Delay);
}
}
}
else
// 3 connect attempts
WifiConnect(3);
#ifdef FEATURE_REPORTING
ReportStatus();
@@ -729,42 +803,11 @@ void setup()
// Setup MQTT Client
byte ProtocolIndex = getProtocolIndex(Settings.Protocol[0]);
if (Protocol[ProtocolIndex].usesMQTT)
if (Protocol[ProtocolIndex].usesMQTT && Settings.ControllerEnabled[0])
MQTTConnect();
sendSysInfoUDP(3);
//warm boot
if (readFromRTC())
{
readUserVarFromRTC();
if (RTC.deepSleepState == 1)
{
log = F("INIT : Rebooted from deepsleep");
lastBootCause=BOOT_CAUSE_DEEP_SLEEP;
}
else
log = F("INIT : Normal boot");
}
//cold boot (RTC memory empty)
else
{
RTC.factoryResetCounter=0;
RTC.deepSleepState=0;
RTC.rebootCounter=0;
RTC.flashDayCounter=0;
RTC.flashCounter=0;
saveToRTC();
// cold boot situation
if (lastBootCause == BOOT_CAUSE_MANUAL_REBOOT) // only set this if not set earlier during boot stage.
lastBootCause = BOOT_CAUSE_COLD_BOOT;
log = F("INIT : Cold Boot");
}
addLog(LOG_LEVEL_INFO, log);
if (Settings.UseNTP)
initTime();
@@ -784,8 +827,7 @@ void setup()
rulesProcessing(event);
}
RTC.deepSleepState=0;
saveToRTC();
writeDefaultCSS();
}
@@ -800,14 +842,10 @@ void loop()
if (wifiSetupConnect)
{
// try to connect for setup wizard
WifiConnect(true,1);
WifiConnect(1);
wifiSetupConnect = false;
}
if (Settings.UseSerial)
if (Serial.available())
if (!PluginCall(PLUGIN_SERIAL_IN, 0, dummyString))
serial();
// Deep sleep mode, just run all tasks one time and go back to sleep as fast as possible
if (isDeepSleepEnabled())
@@ -860,7 +898,6 @@ void run10TimesPerSecond()
start = micros();
timer100ms = millis() + 100;
PluginCall(PLUGIN_TEN_PER_SECOND, 0, dummyString);
checkUDP();
if (Settings.UseRules && eventBuffer.length() > 0)
{
rulesProcessing(eventBuffer);
@@ -948,6 +985,12 @@ void runOncePerSecond()
Serial.print(F(" uS 1 ps:"));
Serial.println(timer);
}
if (timerAPoff != 0 && millis() > timerAPoff)
{
timerAPoff = 0;
WifiAPMode(false);
}
}
/*********************************************************************************************\
@@ -965,7 +1008,8 @@ void runEach30Seconds()
addLog(LOG_LEVEL_INFO, log);
sendSysInfoUDP(1);
refreshNodeList();
MQTTCheck();
if(Settings.ControllerEnabled[0])
MQTTCheck();
if (Settings.UseSSDP)
SSDP_update();
#if FEATURE_ADC_VCC
@@ -1162,14 +1206,31 @@ boolean checkSystemTimers()
/*********************************************************************************************\
* run background tasks
\*********************************************************************************************/
bool runningBackgroundTasks=false;
void backgroundtasks()
{
//prevent recursion!
if (runningBackgroundTasks)
{
yield();
return;
}
runningBackgroundTasks=true;
tcpCleanup();
if (Settings.UseSerial)
if (Serial.available())
if (!PluginCall(PLUGIN_SERIAL_IN, 0, dummyString))
serial();
// process DNS, only used if the ESP has no valid WiFi config
if (wifiSetup)
dnsServer.processNextRequest();
WebServer.handleClient();
MQTTclient.loop();
if(Settings.ControllerEnabled[0])
MQTTclient.loop();
checkUDP();
#ifdef FEATURE_ARDUINO_OTA
@@ -1187,4 +1248,6 @@ void backgroundtasks()
yield();
statusLED(false);
runningBackgroundTasks=false;
}
+308 -124
View File
@@ -1,4 +1,16 @@
// clean up tcp connections that are in TIME_WAIT status, to conserve memory
// In future versions of WiFiClient it should be possible to call abort(), but
// this feature is not in all upstream versions yet.
// See https://github.com/esp8266/Arduino/issues/1923
// and https://github.com/letscontrolit/ESPEasy/issues/253
void tcpCleanup()
{
while(tcp_tw_pcbs!=NULL)
{
tcp_abort(tcp_tw_pcbs);
}
}
bool isDeepSleepEnabled()
{
@@ -11,14 +23,14 @@ bool isDeepSleepEnabled()
// short 2-3 to cancel sleep loop for modifying settings
pinMode(16,INPUT_PULLUP);
if (!digitalRead(16))
{
return false;
}
return true;
}
void deepSleep(int delay)
{
String log;
if (!isDeepSleepEnabled())
{
@@ -29,28 +41,33 @@ void deepSleep(int delay)
//first time deep sleep? offer a way to escape
if (lastBootCause!=BOOT_CAUSE_DEEP_SLEEP)
{
log = F("Entering deep sleep in 30 seconds.");
addLog(LOG_LEVEL_INFO, log);
delayMillis(30000);
addLog(LOG_LEVEL_INFO, F("SLEEP: Entering deep sleep in 30 seconds."));
delayBackground(30000);
//disabled?
if (!isDeepSleepEnabled())
{
log = F("Deep sleep disabled.");
addLog(LOG_LEVEL_INFO, log);
addLog(LOG_LEVEL_INFO, F("SLEEP: Deep sleep cancelled (GPIO16 connected to GND)"));
return;
}
}
log = F("Entering deep sleep...");
addLog(LOG_LEVEL_INFO, log);
deepSleepStart(delay); // Call deepSleepStart function after these checks
}
void deepSleepStart(int delay)
{
// separate function that is called from above function or directly from rules, usign deepSleep as a one-shot
String event = F("System#Sleep");
rulesProcessing(event);
RTC.deepSleepState = 1;
saveToRTC();
String event = F("System#Sleep");
rulesProcessing(event);
if (delay > 4294 || delay < 0)
delay = 4294; //max sleep time ~1.2h
addLog(LOG_LEVEL_INFO, F("SLEEP: Powering down to deepsleep..."));
ESP.deepSleep((uint32_t)delay * 1000000, WAKE_RF_DEFAULT);
}
@@ -345,72 +362,73 @@ boolean timeOut(unsigned long timer)
/********************************************************************************************\
Status LED
\*********************************************************************************************/
#define STATUS_PWM_LOWACTIVE
#define STATUS_PWM_NORMALVALUE (PWMRANGE>>2)
#define STATUS_PWM_NORMALFADE (PWMRANGE>>8)
#define STATUS_PWM_TRAFFICRISE (PWMRANGE>>1)
\*********************************************************************************************/
#define STATUS_PWM_NORMALVALUE (PWMRANGE>>2)
#define STATUS_PWM_NORMALFADE (PWMRANGE>>8)
#define STATUS_PWM_TRAFFICRISE (PWMRANGE>>1)
void statusLED(boolean traffic)
{
static int gnStatusValueCurrent = -1;
static long int gnLastUpdate = millis();
if (Settings.Pin_status_led == -1)
static int gnStatusValueCurrent = -1;
static long int gnLastUpdate = millis();
if (Settings.Pin_status_led == -1)
return;
if (gnStatusValueCurrent<0)
pinMode(Settings.Pin_status_led, OUTPUT);
int nStatusValue = gnStatusValueCurrent;
if (traffic)
if (gnStatusValueCurrent<0)
pinMode(Settings.Pin_status_led, OUTPUT);
int nStatusValue = gnStatusValueCurrent;
if (traffic)
{
nStatusValue += STATUS_PWM_TRAFFICRISE; //ramp up fast
}
else
{
if (AP_Mode) //apmode is active
{
nStatusValue = ((millis()>>1) & PWMRANGE) - (PWMRANGE>>2); //ramp up for 2 sec, 3/4 luminosity
}
else if (WiFi.status() != WL_CONNECTED)
{
nStatusValue = (millis()>>1) & (PWMRANGE>>2); //ramp up for 1/2 sec, 1/4 luminosity
}
else //connected
{
long int delta=millis()-gnLastUpdate;
if (delta>0 || delta<0 )
{
nStatusValue -= STATUS_PWM_NORMALFADE; //ramp down slowly
nStatusValue = std::max(nStatusValue, STATUS_PWM_NORMALVALUE);
gnLastUpdate=millis();
}
}
}
nStatusValue = constrain(nStatusValue, 0, PWMRANGE);
if (gnStatusValueCurrent != nStatusValue)
{
gnStatusValueCurrent = nStatusValue;
long pwm = nStatusValue * nStatusValue; //simple gamma correction
pwm >>= 10;
#ifdef STATUS_PWM_LOWACTIVE
pwm = PWMRANGE-pwm;
#endif
analogWrite(Settings.Pin_status_led, pwm);
}
nStatusValue += STATUS_PWM_TRAFFICRISE; //ramp up fast
}
else
{
if (WiFi.status() == WL_CONNECTED)
{
long int delta=millis()-gnLastUpdate;
if (delta>0 || delta<0 )
{
nStatusValue -= STATUS_PWM_NORMALFADE; //ramp down slowly
nStatusValue = std::max(nStatusValue, STATUS_PWM_NORMALVALUE);
gnLastUpdate=millis();
}
}
//AP mode is active
else if (WifiIsAP())
{
nStatusValue = ((millis()>>1) & PWMRANGE) - (PWMRANGE>>2); //ramp up for 2 sec, 3/4 luminosity
}
//Disconnected
else
{
nStatusValue = (millis()>>1) & (PWMRANGE>>2); //ramp up for 1/2 sec, 1/4 luminosity
}
}
nStatusValue = constrain(nStatusValue, 0, PWMRANGE);
if (gnStatusValueCurrent != nStatusValue)
{
gnStatusValueCurrent = nStatusValue;
long pwm = nStatusValue * nStatusValue; //simple gamma correction
pwm >>= 10;
if (Settings.Pin_status_led_Inversed)
pwm = PWMRANGE-pwm;
analogWrite(Settings.Pin_status_led, pwm);
}
}
/********************************************************************************************\
delay in milliseconds with background processing
\*********************************************************************************************/
void delayMillis(unsigned long delay)
void delayBackground(unsigned long delay)
{
unsigned long timer = millis() + delay;
while (millis() < timer)
@@ -432,10 +450,14 @@ void parseCommandString(struct EventStruct *event, String& string)
event->Par1 = 0;
event->Par2 = 0;
event->Par3 = 0;
event->Par4 = 0;
event->Par5 = 0;
if (GetArgv(command, TmpStr1, 2)) event->Par1 = str2int(TmpStr1);
if (GetArgv(command, TmpStr1, 3)) event->Par2 = str2int(TmpStr1);
if (GetArgv(command, TmpStr1, 4)) event->Par3 = str2int(TmpStr1);
if (GetArgv(command, TmpStr1, 5)) event->Par4 = str2int(TmpStr1);
if (GetArgv(command, TmpStr1, 6)) event->Par5 = str2int(TmpStr1);
}
/********************************************************************************************\
@@ -511,10 +533,18 @@ void BuildFixes()
\*********************************************************************************************/
void fileSystemCheck()
{
addLog(LOG_LEVEL_INFO, F("FS : Mounting..."));
if (SPIFFS.begin())
{
String log = F("FS : Mount successful");
fs::FSInfo fs_info;
SPIFFS.info(fs_info);
String log = F("FS : Mount successful, used ");
log=log+fs_info.usedBytes;
log=log+F(" bytes of ");
log=log+fs_info.totalBytes;
addLog(LOG_LEVEL_INFO, log);
fs::File f = SPIFFS.open("config.dat", "r");
if (!f)
{
@@ -526,6 +556,7 @@ void fileSystemCheck()
String log = F("FS : Mount failed");
Serial.println(log);
addLog(LOG_LEVEL_ERROR, log);
ResetFactory();
}
}
@@ -719,7 +750,7 @@ boolean SaveCustomTaskSettings(int TaskIndex, byte* memAddress, int datasize)
/********************************************************************************************\
Save Custom Task settings to SPIFFS
Load Custom Task settings to SPIFFS
\*********************************************************************************************/
void LoadCustomTaskSettings(int TaskIndex, byte* memAddress, int datasize)
{
@@ -740,7 +771,7 @@ boolean SaveControllerSettings(int ControllerIndex, byte* memAddress, int datasi
/********************************************************************************************\
Save Controller settings to SPIFFS
Load Controller settings to SPIFFS
\*********************************************************************************************/
void LoadControllerSettings(int ControllerIndex, byte* memAddress, int datasize)
{
@@ -752,22 +783,22 @@ void LoadControllerSettings(int ControllerIndex, byte* memAddress, int datasize)
/********************************************************************************************\
Save Custom Controller settings to SPIFFS
\*********************************************************************************************/
boolean SaveCustomControllerSettings(byte* memAddress, int datasize)
boolean SaveCustomControllerSettings(int ControllerIndex,byte* memAddress, int datasize)
{
if (datasize > 4096)
if (datasize > DAT_CUSTOM_CONTROLLER_SIZE)
return false;
return SaveToFile((char*)"config.dat", DAT_OFFSET_CUSTOMCONTROLLER, memAddress, datasize);
return SaveToFile((char*)"config.dat", DAT_OFFSET_CUSTOM_CONTROLLER + (ControllerIndex * DAT_CUSTOM_CONTROLLER_SIZE), memAddress, datasize);
}
/********************************************************************************************\
Save Custom Controller settings to SPIFFS
Load Custom Controller settings to SPIFFS
\*********************************************************************************************/
void LoadCustomControllerSettings(byte* memAddress, int datasize)
void LoadCustomControllerSettings(int ControllerIndex,byte* memAddress, int datasize)
{
if (datasize > 4096)
if (datasize > DAT_CUSTOM_CONTROLLER_SIZE)
return;
LoadFromFile((char*)"config.dat", DAT_OFFSET_CUSTOMCONTROLLER, memAddress, datasize);
LoadFromFile((char*)"config.dat", DAT_OFFSET_CUSTOM_CONTROLLER + (ControllerIndex * DAT_CUSTOM_CONTROLLER_SIZE), memAddress, datasize);
}
/********************************************************************************************\
@@ -782,7 +813,7 @@ boolean SaveNotificationSettings(int NotificationIndex, byte* memAddress, int da
/********************************************************************************************\
Save Controller settings to SPIFFS
Load Controller settings to SPIFFS
\*********************************************************************************************/
void LoadNotificationSettings(int NotificationIndex, byte* memAddress, int datasize)
{
@@ -800,7 +831,7 @@ boolean SaveToFile(char* fname, int index, byte* memAddress, int datasize)
if (RTC.flashDayCounter > MAX_FLASHWRITES_PER_DAY)
{
String log = F("FS : Daily flash write rate exceeded!");
String log = F("FS : Daily flash write rate exceeded! (powercycle to reset this)");
addLog(LOG_LEVEL_ERROR, log);
return false;
}
@@ -863,33 +894,35 @@ void ResetFactory(void)
{
// Direct Serial is allowed here, since this is only an emergency task.
Serial.println(F("Resetting factory defaults..."));
Serial.println(F("RESET: Resetting factory defaults..."));
delay(1000);
if (readFromRTC())
{
Serial.print(F("RESET: Reboot count: "));
Serial.print(F("RESET: Warm boot, reset count: "));
Serial.println(RTC.factoryResetCounter);
if (RTC.factoryResetCounter > 3)
{
Serial.println(F("RESET: To many reset attempts"));
Serial.println(F("RESET: Too many resets, protecting your flash memory (powercycle to solve this)"));
return;
}
}
else
{
Serial.println(F("RESET: Cold boot"));
initRTC();
}
RTC.factoryResetCounter++;
RTC.flashDayCounter = 0;
saveToRTC();
//always format on factory reset, in case of corrupt SPIFFS
SPIFFS.end();
Serial.println(F("FS : formatting..."));
Serial.println(F("RESET: formatting..."));
SPIFFS.format();
Serial.println(F("FS : formatting done..."));
Serial.println(F("RESET: formatting done..."));
if (!SPIFFS.begin())
{
Serial.println(F("FS : FORMATTING SPIFFS FAILED!"));
Serial.println(F("RESET: FORMAT SPIFFS FAILED!"));
return;
}
@@ -930,11 +963,6 @@ void ResetFactory(void)
str2ip((char*)DEFAULT_SUBNET, Settings.Subnet);
#endif
#if DEFAULT_MQTT_TEMPLATE
strcpy_P(Settings.MQTTsubscribe, PSTR(DEFAULT_MQTT_SUB));
strcpy_P(Settings.MQTTpublish, PSTR(DEFAULT_MQTT_PUB));
#endif
Settings.PID = ESP_PROJECT_PID;
Settings.Version = VERSION;
Settings.Unit = UNIT;
@@ -942,12 +970,11 @@ void ResetFactory(void)
strcpy_P(SecuritySettings.WifiKey, PSTR(DEFAULT_KEY));
strcpy_P(SecuritySettings.WifiAPKey, PSTR(DEFAULT_AP_KEY));
SecuritySettings.Password[0] = 0;
//str2ip((char*)DEFAULT_SERVER, Settings.Controller_IP[0]);
//Settings.ControllerPort[0] = DEFAULT_PORT;
Settings.Delay = DEFAULT_DELAY;
Settings.Pin_i2c_sda = 4;
Settings.Pin_i2c_scl = 5;
Settings.Pin_status_led = -1;
Settings.Pin_status_led_Inversed = true;
Settings.Pin_sd_cs = -1;
Settings.Protocol[0] = DEFAULT_PROTOCOL;
strcpy_P(Settings.Name, PSTR(DEFAULT_NAME));
@@ -972,7 +999,19 @@ void ResetFactory(void)
Settings.Build = BUILD;
Settings.UseSerial = true;
SaveSettings();
Serial.println("Factory reset succesful, rebooting...");
#if DEFAULT_CONTROLLER
ControllerSettingsStruct ControllerSettings;
strcpy_P(ControllerSettings.Subscribe, PSTR(DEFAULT_SUB));
strcpy_P(ControllerSettings.Publish, PSTR(DEFAULT_PUB));
str2ip((char*)DEFAULT_SERVER, ControllerSettings.IP);
ControllerSettings.HostName[0]=0;
ControllerSettings.Port = DEFAULT_PORT;
SaveControllerSettings(0, (byte*)&ControllerSettings, sizeof(ControllerSettings));
#endif
Serial.println("RESET: Succesful, rebooting. (you might need to press the reset button if you've justed flashed the firmware)");
//NOTE: this is a known ESP8266 bug, not our fault. :)
delay(1000);
WiFi.persistent(true); // use SDK storage of SSID/WPA parameters
WiFi.disconnect(); // this will store empty ssid/wpa into sdk storage
@@ -1032,6 +1071,7 @@ float ul2float(unsigned long ul)
return f;
}
/********************************************************************************************\
Init critical variables for logging (important during initial factory reset stuff )
\*********************************************************************************************/
@@ -1043,7 +1083,7 @@ void initLog()
Settings.SerialLogLevel=2; //logging during initialisation
Settings.WebLogLevel=2;
Settings.SDLogLevel=0;
for (int l; l<9; l++)
for (int l=0; l<10; l++)
{
Logging[l].Message=0;
}
@@ -1115,47 +1155,91 @@ void delayedReboot(int rebootDelay)
/********************************************************************************************\
Save RTC struct to RTC memory
\*********************************************************************************************/
#define RTC_BASE_STRUCT 64
void saveToRTC()
boolean saveToRTC()
{
RTC.ID1 = 0xAA;
RTC.ID2 = 0x55;
RTC.valid = true;
system_rtc_mem_write(RTC_BASE_STRUCT, (byte*)&RTC, sizeof(RTC));
if (!system_rtc_mem_write(RTC_BASE_STRUCT, (byte*)&RTC, sizeof(RTC)) || !readFromRTC())
{
addLog(LOG_LEVEL_ERROR, F("RTC : Error while writing to RTC"));
return(false);
}
else
{
return(true);
}
}
/********************************************************************************************\
Initialize RTC memory
\*********************************************************************************************/
void initRTC()
{
memset(&RTC, 0, sizeof(RTC));
RTC.ID1 = 0xAA;
RTC.ID2 = 0x55;
saveToRTC();
memset(&UserVar, 0, sizeof(UserVar));
saveUserVarToRTC();
}
/********************************************************************************************\
Read RTC struct from RTC memory
\*********************************************************************************************/
boolean readFromRTC()
{
system_rtc_mem_read(RTC_BASE_STRUCT, (byte*)&RTC, sizeof(RTC));
if (!system_rtc_mem_read(RTC_BASE_STRUCT, (byte*)&RTC, sizeof(RTC)))
return(false);
if (RTC.ID1 == 0xAA && RTC.ID2 == 0x55)
{
RTC.valid = false;
return true;
}
return false;
else
return false;
}
/********************************************************************************************\
Save values to RTC memory
\*********************************************************************************************/
#define RTC_BASE_USERVAR 74
void saveUserVarToRTC()
\*********************************************************************************************/
boolean saveUserVarToRTC()
{
system_rtc_mem_write(RTC_BASE_USERVAR, (byte*)&UserVar, sizeof(UserVar));
//addLog(LOG_LEVEL_DEBUG, F("RTCMEM: saveUserVarToRTC"));
byte* buffer = (byte*)&UserVar;
size_t size = sizeof(UserVar);
uint32 sum = getChecksum(buffer, size);
boolean ret = system_rtc_mem_write(RTC_BASE_USERVAR, buffer, size);
ret &= system_rtc_mem_write(RTC_BASE_USERVAR+(size>>2), (byte*)&sum, 4);
return ret;
}
/********************************************************************************************\
Read RTC struct from RTC memory
\*********************************************************************************************/
\*********************************************************************************************/
boolean readUserVarFromRTC()
{
system_rtc_mem_read(RTC_BASE_USERVAR, (byte*)&UserVar, sizeof(UserVar));
//addLog(LOG_LEVEL_DEBUG, F("RTCMEM: readUserVarFromRTC"));
byte* buffer = (byte*)&UserVar;
size_t size = sizeof(UserVar);
boolean ret = system_rtc_mem_read(RTC_BASE_USERVAR, buffer, size);
uint32 sumRAM = getChecksum(buffer, size);
uint32 sumRTC = 0;
ret &= system_rtc_mem_read(RTC_BASE_USERVAR+(size>>2), (byte*)&sumRTC, 4);
if (!ret || sumRTC != sumRAM)
{
addLog(LOG_LEVEL_ERROR, F("RTC : Checksum error on reading RTC user var"));
memset(buffer, 0, size);
}
return ret;
}
uint32 getChecksum(byte* buffer, size_t size)
{
uint32 sum = 0x82662342; //some magic to avoid valid checksum on new, uninitialized ESP
for (size_t i=0; i<size; i++)
sum += buffer[i];
return sum;
}
@@ -1264,6 +1348,70 @@ String timeLong2String(unsigned long lngTime)
return time;
}
// returns the current Date separated by the given delimiter
// date format example with '-' delimiter: 2016-12-31 (YYYY-MM-DD)
String getDateString(char delimiter)
{
String reply = String(year());
if (delimiter != '\0')
reply += delimiter;
if (month() < 10)
reply += "0";
reply += month();
if (delimiter != '\0')
reply += delimiter;
if (day() < 10)
reply += F("0");
reply += day();
return reply;
}
// returns the current Date without delimiter
// date format example: 20161231 (YYYYMMDD)
String getDateString()
{
return getDateString('\0');
}
// returns the current Time separated by the given delimiter
// time format example with ':' delimiter: 23:59:59 (HH:MM:SS)
String getTimeString(char delimiter)
{
String reply;
if (hour() < 10)
reply += F("0");
reply += String(hour());
if (delimiter != '\0')
reply += delimiter;
if (minute() < 10)
reply += F("0");
reply += minute();
if (delimiter != '\0')
reply += delimiter;
if (second() < 10)
reply += F("0");
reply += second();
return reply;
}
// returns the current Time without delimiter
// time format example: 235959 (HHMMSS)
String getTimeString()
{
return getTimeString('\0');
}
// returns the current Date and Time separated by the given delimiter
// if called like this: getDateTimeString('\0', '\0', '\0');
// it will give back this: 20161231235959 (YYYYMMDDHHMMSS)
String getDateTimeString(char dateDelimiter, char timeDelimiter, char dateTimeDelimiter)
{
String ret = getDateString(dateDelimiter);
if (dateTimeDelimiter != '\0')
ret += dateTimeDelimiter;
ret += getTimeString(timeDelimiter);
return ret;
}
/********************************************************************************************\
Match clock event
@@ -1381,15 +1529,7 @@ String parseTemplate(String &tmpString, byte lineSize)
// replace other system variables like %sysname%, %systime%, %ip%
newString.replace(F("%sysname%"), Settings.Name);
String strTime = "";
if (hour() < 10)
strTime += " ";
strTime += hour();
strTime += ":";
if (minute() < 10)
strTime += "0";
strTime += minute();
newString.replace(F("%systime%"), strTime);
newString.replace(F("%systime%"), getTimeString(':'));
newString.replace(F("%uptime%"), String(wdcounter / 2));
@@ -1813,6 +1953,11 @@ byte minute()
return tm.Minute;
}
byte second()
{
return tm.Second;
}
int weekday()
{
return tm.Wday;
@@ -2329,14 +2474,53 @@ void createRuleEvents(byte TaskIndex)
}
}
void checkRAM(byte id)
void SendValueLogger(byte TaskIndex)
{
String logger;
LoadTaskSettings(TaskIndex);
byte BaseVarIndex = TaskIndex * VARS_PER_TASK;
byte DeviceIndex = getDeviceIndex(Settings.TaskDeviceNumber[TaskIndex]);
byte sensorType = Device[DeviceIndex].VType;
for (byte varNr = 0; varNr < Device[DeviceIndex].ValueCount; varNr++)
{
logger += getDateString('-');
logger += F(" ");
logger += getTimeString(':');
logger += F(",");
logger += Settings.Unit;
logger += F(",");
logger += ExtraTaskSettings.TaskDeviceName;
logger += F(",");
logger += ExtraTaskSettings.TaskDeviceValueNames[varNr];
logger += F(",");
if (sensorType == SENSOR_TYPE_LONG)
logger += (unsigned long)UserVar[BaseVarIndex] + ((unsigned long)UserVar[BaseVarIndex + 1] << 16);
else
logger += String(UserVar[BaseVarIndex + varNr], ExtraTaskSettings.TaskDeviceValueDecimals[varNr]);
logger += F("\r\n");
}
addLog(LOG_LEVEL_DEBUG, logger);
String filename = F("VALUES.CSV");
File logFile = SD.open(filename, FILE_WRITE);
if (logFile)
logFile.print(logger);
logFile.close();
}
void checkRAM( const __FlashStringHelper* flashString)
{
uint16_t freeRAM = FreeMem();
if (freeRAM < lowestRAM)
{
lowestRAM = freeRAM;
lowestRAMid = id;
lowestRAMfunction = flashString;
}
}
@@ -2600,4 +2784,4 @@ void htmlEscape(String & html)
html.replace("'", "&#039;");
html.replace("<", "&lt;");
html.replace(">", "&gt;");
}
}
+10 -2
View File
@@ -48,8 +48,10 @@ struct dataStruct
float Values[VARS_PER_TASK];
};
//TODO: add sysinfoStruct
/*********************************************************************************************\
Check UDP messages
Check UDP messages (ESPEasy propiertary protocol)
\*********************************************************************************************/
void checkUDP()
{
@@ -98,6 +100,8 @@ void checkUDP()
// binary data!
switch (packetBuffer[1])
{
//TODO: use a nice struct for it
case 1: // sysinfo message
{
byte mac[6];
@@ -289,7 +293,7 @@ void SendUDPCommand(byte destUnit, char* data, byte dataLength)
/*********************************************************************************************\
Send UDP message
Send UDP message (unit 255=broadcast)
\*********************************************************************************************/
void sendUDP(byte unit, byte* data, byte size)
{
@@ -330,12 +334,16 @@ void refreshNodeList()
}
}
/*********************************************************************************************\
Broadcast system info to other nodes. (to update node lists)
\*********************************************************************************************/
void sendSysInfoUDP(byte repeats)
{
char log[80];
if (Settings.UDPPort == 0)
return;
// TODO: make a nice struct of it and clean up
// 1 byte 'binary token 255'
// 1 byte id '1'
// 6 byte mac
+3 -2
View File
@@ -25,8 +25,10 @@ void serial()
InputBuffer_Serial[SerialInByteCounter++] = SerialInByte;
}
if (SerialInByte == '\n')
if (SerialInByte == '\r' || SerialInByte == '\n')
{
if (SerialInByteCounter == 0) //empty command?
break;
InputBuffer_Serial[SerialInByteCounter] = 0; // serial data completed
Serial.write('>');
Serial.println(InputBuffer_Serial);
@@ -41,4 +43,3 @@ void serial()
}
}
}
+1504 -767
View File
File diff suppressed because it is too large Load Diff
+165 -101
View File
@@ -1,52 +1,90 @@
//********************************************************************************
// Determine Wifi AP name to set. (also used for mDNS)
//********************************************************************************
String WifiGetAPssid()
{
String ssid(Settings.Name);
ssid+=F("_");
ssid+=Settings.Unit;
return (ssid);
}
//********************************************************************************
// Determine hostname: basically WifiGetAPssid with spaces changed to -
//********************************************************************************
String WifiGetHostname()
{
String hostname(WifiGetAPssid());
hostname.replace(F(" "), F("-"));
return (hostname);
}
//********************************************************************************
// 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!
char ap_ssid[20];
ap_ssid[0] = 0;
strcpy(ap_ssid, "ESP_");
sprintf_P(ap_ssid, PSTR("%s%u"), ap_ssid, Settings.Unit);
// setup ssid for AP Mode when needed
WiFi.softAP(ap_ssid, SecuritySettings.WifiAPKey);
WiFi.softAP(WifiGetAPssid().c_str(), SecuritySettings.WifiAPKey);
// We start in STA mode
WiFi.mode(WIFI_STA);
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()
{
byte wifimode = wifi_get_opmode();
return(wifimode == 2 || wifimode == 3); //apmode is enabled
}
//********************************************************************************
// Set Wifi AP Mode
//********************************************************************************
void WifiAPMode(boolean state)
{
if (state)
if (WifiIsAP())
{
AP_Mode = true;
WiFi.mode(WIFI_AP_STA);
//want to disable?
if (!state)
{
WiFi.mode(WIFI_STA);
addLog(LOG_LEVEL_INFO, F("WIFI : AP Mode disabled"));
}
}
else
{
AP_Mode = false;
WiFi.mode(WIFI_STA);
//want to enable?
if (state)
{
WiFi.mode(WIFI_AP_STA);
addLog(LOG_LEVEL_INFO, F("WIFI : AP Mode enabled"));
}
}
}
//********************************************************************************
// Connect to Wifi AP
// Configure network and connect to Wifi SSID and SSID2
//********************************************************************************
boolean WifiConnect(boolean primary, byte connectAttempts)
boolean WifiConnect(byte connectAttempts)
{
String log = "";
char hostname[40];
strncpy(hostname, WifiGetHostname().c_str(), sizeof(hostname));
wifi_station_set_hostname(hostname);
char hostName[sizeof(Settings.Name)];
strcpy(hostName,Settings.Name);
for(byte x=0; x< sizeof(hostName); x++)
if (hostName[x] == ' ')
hostName[x] = '-';
wifi_station_set_hostname(hostName);
//use static ip?
if (Settings.IP[0] != 0 && Settings.IP[0] != 255)
{
char str[20];
@@ -61,87 +99,120 @@ boolean WifiConnect(boolean primary, byte connectAttempts)
WiFi.config(ip, gw, subnet, dns);
}
if (WiFi.status() != WL_CONNECTED)
//try to connect to one of the access points
if (WifiConnectSSID(SecuritySettings.WifiSSID, SecuritySettings.WifiKey, connectAttempts) ||
WifiConnectSSID(SecuritySettings.WifiSSID2, SecuritySettings.WifiKey2, connectAttempts))
{
if ((SecuritySettings.WifiSSID[0] != 0) && (strcasecmp(SecuritySettings.WifiSSID, "ssid") != 0))
// fix octet?
if (Settings.IP_Octet != 0 && Settings.IP_Octet != 255)
{
for (byte tryConnect = 1; tryConnect <= connectAttempts; tryConnect++)
{
log = F("WIFI : Connecting... ");
log += tryConnect;
addLog(LOG_LEVEL_INFO, log);
IPAddress ip = WiFi.localIP();
IPAddress gw = WiFi.gatewayIP();
IPAddress subnet = WiFi.subnetMask();
ip[3] = Settings.IP_Octet;
log = F("IP : Fixed IP octet:");
log += ip;
addLog(LOG_LEVEL_INFO, log);
WiFi.config(ip, gw, subnet);
}
if (tryConnect == 1)
{
if (primary)
WiFi.begin(SecuritySettings.WifiSSID, SecuritySettings.WifiKey);
else
WiFi.begin(SecuritySettings.WifiSSID2, SecuritySettings.WifiKey2);
}
else
WiFi.begin();
#ifdef FEATURE_MDNS
for (byte x = 0; x < 200; x++)
{
if (WiFi.status() != WL_CONNECTED)
{
statusLED(false);
delay(50);
}
else
break;
}
if (WiFi.status() == WL_CONNECTED)
{
log = F("WIFI : Connected! IP: ");
IPAddress ip = WiFi.localIP();
char str[20];
sprintf_P(str, PSTR("%u.%u.%u.%u"), ip[0], ip[1], ip[2], ip[3]);
log += str;
addLog(LOG_LEVEL_INFO, log);
statusLED(true);
break;
}
else
{
log = F("WIFI : Disconnecting!");
addLog(LOG_LEVEL_INFO, log);
ETS_UART_INTR_DISABLE();
wifi_station_disconnect();
ETS_UART_INTR_ENABLE();
for (byte x = 0; x < 20; x++)
{
statusLED(true);
delay(50);
}
}
String log = F("WIFI : ");
if (MDNS.begin(WifiGetHostname().c_str(), WiFi.localIP())) {
log += F("mDNS started, with name: ");
log += WifiGetHostname();
log += F(".local");
}
// fix ip if last octet is set
if (Settings.IP_Octet != 0 && Settings.IP_Octet != 255)
{
IPAddress ip = WiFi.localIP();
IPAddress gw = WiFi.gatewayIP();
IPAddress subnet = WiFi.subnetMask();
ip[3] = Settings.IP_Octet;
log = F("IP : Fixed IP :");
log += ip;
addLog(LOG_LEVEL_INFO, log);
WiFi.config(ip, gw, subnet);
else{
log += F("mDNS failed");
}
addLog(LOG_LEVEL_INFO, log);
#endif
return(true);
}
addLog(LOG_LEVEL_ERROR, F("WIFI : Could not connect to AP!"));
//everything failed, activate AP mode (will deactivate automaticly after a while if its connected again)
WifiAPMode(true);
return(false);
}
//********************************************************************************
// Connect to Wifi specific SSID
//********************************************************************************
boolean WifiConnectSSID(char WifiSSID[], char WifiKey[], byte connectAttempts)
{
String log;
//already connected, need to disconnect first
if (WiFi.status() == WL_CONNECTED)
return(true);
//no ssid specified
if ((WifiSSID[0] == 0) || (strcasecmp(WifiSSID, "ssid") == 0))
return(false);
for (byte tryConnect = 1; tryConnect <= connectAttempts; tryConnect++)
{
log = F("WIFI : Connecting ");
log += WifiSSID;
log += F(" attempt #");
log += tryConnect;
addLog(LOG_LEVEL_INFO, log);
if (tryConnect == 1)
WiFi.begin(WifiSSID, WifiKey);
else
WiFi.begin();
//wait until it connects
for (byte x = 0; x < 200; x++)
{
if (WiFi.status() != WL_CONNECTED)
{
statusLED(false);
delay(50);
}
else
break;
}
if (WiFi.status() == WL_CONNECTED)
{
log = F("WIFI : Connected! IP: ");
IPAddress ip = WiFi.localIP();
char str[20];
sprintf_P(str, PSTR("%u.%u.%u.%u"), ip[0], ip[1], ip[2], ip[3]);
log += str;
log += F(" (");
log += WifiGetHostname();
log += F(")");
addLog(LOG_LEVEL_INFO, log);
statusLED(true);
return(true);
}
else
{
log = F("WIFI : No SSID!");
addLog(LOG_LEVEL_INFO, log);
NC_Count = 1;
WifiAPMode(true);
// log = F("WIFI : Disconnecting!");
// addLog(LOG_LEVEL_INFO, log);
ETS_UART_INTR_DISABLE();
wifi_station_disconnect();
ETS_UART_INTR_ENABLE();
for (byte x = 0; x < 20; x++)
{
statusLED(true);
delay(50);
}
}
}
if (WiFi.status() == WL_CONNECTED)
return true;
return false;
}
@@ -203,30 +274,23 @@ void WifiCheck()
if (WiFi.status() != WL_CONNECTED)
{
NC_Count++;
//give it time to automaticly reconnect
if (NC_Count > 2)
{
if (!WifiConnect(true,2))
WifiConnect(false,2);
WifiConnect(2);
C_Count=0;
if (WiFi.status() != WL_CONNECTED)
WifiAPMode(true);
NC_Count = 0;
}
}
//connected
else
{
C_Count++;
NC_Count = 0;
if (C_Count > 2) // close AP after timeout if a Wifi connection is established...
if (C_Count > 2) // disable AP after timeout if a Wifi connection is established...
{
byte wifimode = wifi_get_opmode();
if (wifimode == 2 || wifimode == 3) //apmode is active
{
WifiAPMode(false);
log = F("WIFI : AP Mode inactive");
addLog(LOG_LEVEL_INFO, log);
}
WifiAPMode(false);
}
}
}
+1 -1
View File
@@ -37,7 +37,7 @@ boolean CPlugin_001(byte function, struct EventStruct *event, String& string)
LoadControllerSettings(event->ControllerIndex, (byte*)&ControllerSettings, sizeof (ControllerSettings));
String authHeader = "";
if ((SecuritySettings.ControllerUser[event->ProtocolIndex][0] != 0) && (SecuritySettings.ControllerPassword[event->ProtocolIndex][0] != 0))
if ((SecuritySettings.ControllerUser[event->ControllerIndex][0] != 0) && (SecuritySettings.ControllerPassword[event->ControllerIndex][0] != 0))
{
base64 encoder;
String auth = SecuritySettings.ControllerUser[event->ControllerIndex];
+4 -3
View File
@@ -49,9 +49,10 @@ boolean CPlugin_008(byte function, struct EventStruct *event, String& string)
HTTPSend(event, x, UserVar[event->BaseVarIndex + x], 0);
if (valueCount > 1)
{
unsigned long timer = millis() + Settings.MessageDelay;
while (millis() < timer)
backgroundtasks();
delayBackground(Settings.MessageDelay);
// unsigned long timer = millis() + Settings.MessageDelay;
// while (millis() < timer)
// backgroundtasks();
}
}
break;
+4 -3
View File
@@ -48,9 +48,10 @@ boolean CPlugin_010(byte function, struct EventStruct *event, String& string)
C010_Send(event, x, UserVar[event->BaseVarIndex + x], 0);
if (valueCount > 1)
{
unsigned long timer = millis() + Settings.MessageDelay;
while (millis() < timer)
backgroundtasks();
delayBackground(Settings.MessageDelay);
// unsigned long timer = millis() + Settings.MessageDelay;
// while (millis() < timer)
// backgroundtasks();
}
}
break;
+30 -39
View File
@@ -8,17 +8,17 @@
#define CPLUGIN_ID_011 11
#define CPLUGIN_NAME_011 "Generic HTTP Advanced [TESTING]"
#define P011_HTTP_METHOD_MAX_LEN 16
#define P011_HTTP_URI_MAX_LEN 240
#define P011_HTTP_HEADER_MAX_LEN 256
#define P011_HTTP_BODY_MAX_LEN 512
#define C011_HTTP_METHOD_MAX_LEN 16
#define C011_HTTP_URI_MAX_LEN 240
#define C011_HTTP_HEADER_MAX_LEN 256
#define C011_HTTP_BODY_MAX_LEN 512
struct P011_ConfigStruct
struct C011_ConfigStruct
{
char HttpMethod[P011_HTTP_METHOD_MAX_LEN];
char HttpUri[P011_HTTP_URI_MAX_LEN];
char HttpHeader[P011_HTTP_HEADER_MAX_LEN];
char HttpBody[P011_HTTP_BODY_MAX_LEN];
char HttpMethod[C011_HTTP_METHOD_MAX_LEN];
char HttpUri[C011_HTTP_URI_MAX_LEN];
char HttpHeader[C011_HTTP_HEADER_MAX_LEN];
char HttpBody[C011_HTTP_BODY_MAX_LEN];
};
boolean CPlugin_011(byte function, struct EventStruct *event, String& string)
@@ -48,8 +48,9 @@ boolean CPlugin_011(byte function, struct EventStruct *event, String& string)
{
String escapeBuffer;
P011_ConfigStruct customConfig;
LoadCustomControllerSettings((byte*)&customConfig, sizeof(customConfig));
C011_ConfigStruct customConfig;
LoadCustomControllerSettings(event->ControllerIndex,(byte*)&customConfig, sizeof(customConfig));
String methods[] = { F("GET"), F("POST"), F("PUT"), F("HEAD"), F("PATCH") };
string += F("<TR><TD>HTTP Method :<TD><select name='P011httpmethod'>");
for (byte i = 0; i < 5; i++)
@@ -64,14 +65,14 @@ boolean CPlugin_011(byte function, struct EventStruct *event, String& string)
string += F("</select>");
string += F("<TR><TD>HTTP URI:<TD><input type='text' name='P011httpuri' size=80 maxlength='");
string += P011_HTTP_URI_MAX_LEN-1;
string += C011_HTTP_URI_MAX_LEN-1;
string += F("' value='");
string += customConfig.HttpUri;
string += F("'>");
string += F("<TR><TD>HTTP Header:<TD><textarea name='P011httpheader' rows='4' cols='50' maxlength='");
string += P011_HTTP_HEADER_MAX_LEN-1;
string += C011_HTTP_HEADER_MAX_LEN-1;
string += F("'>");
escapeBuffer=customConfig.HttpHeader;
htmlEscape(escapeBuffer);
@@ -79,7 +80,7 @@ boolean CPlugin_011(byte function, struct EventStruct *event, String& string)
string += F("</textarea>");
string += F("<TR><TD>HTTP Body:<TD><textarea name='P011httpbody' rows='8' cols='50' maxlength='");
string += P011_HTTP_BODY_MAX_LEN-1;
string += C011_HTTP_BODY_MAX_LEN-1;
string += F("'>");
escapeBuffer=customConfig.HttpBody;
htmlEscape(escapeBuffer);
@@ -90,16 +91,17 @@ boolean CPlugin_011(byte function, struct EventStruct *event, String& string)
case CPLUGIN_WEBFORM_SAVE:
{
P011_ConfigStruct customConfig;
C011_ConfigStruct customConfig;
String httpmethod = WebServer.arg(F("P011httpmethod"));
String httpuri = WebServer.arg(F("P011httpuri"));
String httpheader = WebServer.arg(F("P011httpheader"));
String httpbody = WebServer.arg(F("P011httpbody"));
strlcpy(customConfig.HttpMethod, httpmethod.c_str(), sizeof(customConfig.HttpMethod));
strlcpy(customConfig.HttpUri, httpuri.c_str(), sizeof(customConfig.HttpUri));
strlcpy(customConfig.HttpHeader, httpheader.c_str(), sizeof(customConfig.HttpHeader));
strlcpy(customConfig.HttpBody, httpbody.c_str(), sizeof(customConfig.HttpBody));
SaveCustomControllerSettings((byte*)&customConfig, sizeof(customConfig));
SaveCustomControllerSettings(event->ControllerIndex,(byte*)&customConfig, sizeof(customConfig));
break;
}
@@ -133,24 +135,19 @@ boolean HTTPSend011(struct EventStruct *event)
authHeader += F(" \r\n");
}
P011_ConfigStruct customConfig;
LoadCustomControllerSettings((byte*)&customConfig, sizeof(customConfig));
C011_ConfigStruct customConfig;
LoadCustomControllerSettings(event->ControllerIndex,(byte*)&customConfig, sizeof(customConfig));
// char log[80];
boolean success = false;
// char host[20];
IPAddress host(ControllerSettings.IP[0], ControllerSettings.IP[1], ControllerSettings.IP[2], ControllerSettings.IP[3]);
// sprintf_P(host, PSTR("%u.%u.%u.%u"), ControllerSettings.IP[0], ControllerSettings.IP[1], ControllerSettings.IP[2], ControllerSettings.IP[3]);
// char tmp[22];
// strcpy_P(tmp, PSTR("HTTP : connecting to "));
// sprintf_P(log, PSTR("%s%s using port %u"), tmp, host, ControllerSettings.Port);
// addLog(LOG_LEVEL_DEBUG, log);
addLog(LOG_LEVEL_DEBUG, String(F("HTTP : connecting to "))+host.toString()+":"+ControllerSettings.Port);
IPAddress host(ControllerSettings.IP[0], ControllerSettings.IP[1], ControllerSettings.IP[2], ControllerSettings.IP[3]);
addLog(LOG_LEVEL_DEBUG, String(F("HTTP : connecting to "))+
(ControllerSettings.UseDNS ? ControllerSettings.HostName : host.toString() ) +":"+ControllerSettings.Port);
// Use WiFiClient class to create TCP connections
WiFiClient client;
if (!client.connect(host, ControllerSettings.Port))
if (ControllerSettings.UseDNS ? !client.connect(ControllerSettings.HostName, ControllerSettings.Port) : !client.connect(host, ControllerSettings.Port))
{
connectionFailures++;
addLog(LOG_LEVEL_ERROR, F("HTTP : connection failed"));
@@ -165,7 +162,7 @@ boolean HTTPSend011(struct EventStruct *event)
String hostName = host.toString();
if (ControllerSettings.UseDNS)
hostName = ControllerSettings.HostName[event->ProtocolIndex];
hostName = ControllerSettings.HostName;
String payload = String(customConfig.HttpMethod) + " /";
payload += customConfig.HttpUri;
@@ -189,6 +186,7 @@ boolean HTTPSend011(struct EventStruct *event)
payload += F("\r\n\r\n");
payload += body;
}
payload += F("\r\n");
// This will send the request to the server
client.print(payload);
@@ -310,18 +308,11 @@ void ReplaceTokenByValue(String& s, struct EventStruct *event)
addLog(LOG_LEVEL_DEBUG_MORE, s);
//NOTE: cant we just call parseTemplate() for all the standard stuff??
String strTime = "";
if (hour() < 10)
strTime += F(" ");
strTime += hour();
strTime += F(":");
if (minute() < 10)
strTime += F("0");
strTime += minute();
s.replace(F("%systime%"), strTime);
s.replace(F("%systime%"), getTimeString(':'));
#if FEATURE_ADC_VCC
newString.replace(F("%vcc%"), String(vcc));
s.replace(F("%vcc%"), String(vcc));
#endif
// IPAddress ip = WiFi.localIP();
+6 -6
View File
@@ -78,12 +78,12 @@ boolean NPlugin_001_send(String aDomain , String aTo, String aFrom, String aSub,
// The MTA Exchange
while (true) {
if (NPlugin_001_MTA(client, "", PSTR("220 ")) == false) break;
if (NPlugin_001_MTA(client, PSTR("EHLO ") + aDomain, PSTR("250 ")) == false) break;
if (NPlugin_001_MTA(client, PSTR("MAIL FROM:") + aFrom + "", PSTR("250 ")) == false) break;
if (NPlugin_001_MTA(client, PSTR("RCPT TO:") + aTo + "", PSTR("250 ")) == false) break;
if (NPlugin_001_MTA(client, PSTR("DATA"), PSTR("354 ")) == false) break;
if (NPlugin_001_MTA(client, PSTR("Subject:") + aSub + PSTR("\r\n\r\n") + aMesg + PSTR("\r\n.\r\n"), PSTR("250 ")) == false) break;
if (NPlugin_001_MTA(client, "", F("220 ")) == false) break;
if (NPlugin_001_MTA(client, String(F("EHLO ")) + aDomain, F("250 ")) == false) break;
if (NPlugin_001_MTA(client, String(F("MAIL FROM:")) + aFrom + "", F("250 ")) == false) break;
if (NPlugin_001_MTA(client, String(F("RCPT TO:")) + aTo + "", F("250 ")) == false) break;
if (NPlugin_001_MTA(client, F("DATA"), F("354 ")) == false) break;
if (NPlugin_001_MTA(client, String(F("Subject:")) + aSub + F("\r\n\r\n") + aMesg + F("\r\n.\r\n"), F("250 ")) == false) break;
myStatus = true;
break;
+10 -46
View File
@@ -52,22 +52,8 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
String options[2];
options[0] = F("Switch");
options[1] = F("Dimmer");
int optionValues[2];
optionValues[0] = 1;
optionValues[1] = 2;
string += F("<TR><TD>Switch Type:<TD><select name='plugin_001_type'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
int optionValues[2] = { 1, 2 };
addFormSelector(string, F("Switch Type"), F("plugin_001_type"), 2, options, optionValues, choice);
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 2)
{
@@ -81,29 +67,10 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
buttonOptions[0] = F("Normal Switch");
buttonOptions[1] = F("Push Button Active Low");
buttonOptions[2] = F("Push Button Active High");
int buttonOptionValues[3];
buttonOptionValues[0] = 0;
buttonOptionValues[1] = 1;
buttonOptionValues[2] = 2;
string += F("<TR><TD>Switch Button Type:<TD><select name='plugin_001_button'>");
for (byte x = 0; x < 3; x++)
{
string += F("<option value='");
string += buttonOptionValues[x];
string += "'";
if (choice == buttonOptionValues[x])
string += F(" selected");
string += ">";
string += buttonOptions[x];
string += F("</option>");
}
string += F("</select>");
addFormSelector(string, F("Switch Button Type"), F("plugin_001_button"), 3, buttonOptions, NULL, choice);
string += F("<TR><TD>Send Boot state:<TD>");
if (Settings.TaskDevicePluginConfig[event->TaskIndex][3])
string += F("<input type=checkbox name=plugin_001_boot checked>");
else
string += F("<input type=checkbox name=plugin_001_boot>");
addFormCheckBox(string, F("Send Boot state"),F("plugin_001_boot"),
Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
success = true;
break;
@@ -111,18 +78,15 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_001_type"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_001_type"));
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 2)
{
String plugin2 = WebServer.arg(F("plugin_001_dimvalue"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin2.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_001_dimvalue"));
}
String plugin3 = WebServer.arg(F("plugin_001_button"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = plugin3.toInt();
String plugin4 = WebServer.arg(F("plugin_001_boot"));
Settings.TaskDevicePluginConfig[event->TaskIndex][3] = (plugin4 == "on");
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("plugin_001_button"));
Settings.TaskDevicePluginConfig[event->TaskIndex][3] = isFormItemChecked(F("plugin_001_boot"));
success = true;
break;
+86 -5
View File
@@ -6,13 +6,17 @@
#define PLUGIN_ID_002 2
#define PLUGIN_NAME_002 "Analog input"
#define PLUGIN_VALUENAME1_002 "Analog"
uint32_t Plugin_002_OversamplingValue = 0;
uint16_t Plugin_002_OversamplingCount = 0;
boolean Plugin_002(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_002;
@@ -40,13 +44,90 @@ boolean Plugin_002(byte function, struct EventStruct *event, String& string)
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_002));
break;
}
case PLUGIN_WEBFORM_LOAD:
{
addFormCheckBox(string, F("Oversampling"), F("plugin_002_oversampling"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
addFormSubHeader(string, F("Two Point Calibration"));
addFormCheckBox(string, F("Calibration Enabled"), F("plugin_002_cal"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
addFormNumericBox(string, F("Point 1"), F("plugin_002_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], 0, 1023);
string += F(" &#8793; ");
addTextBox(string, F("plugin_002_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
addFormNumericBox(string, F("Point 2"), F("plugin_002_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], 0, 1023);
string += F(" &#8793; ");
addTextBox(string, F("plugin_002_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
success = true;
break;
}
case PLUGIN_WEBFORM_SAVE:
{
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = isFormItemChecked(F("plugin_002_oversampling"));
Settings.TaskDevicePluginConfig[event->TaskIndex][3] = isFormItemChecked(F("plugin_002_cal"));
Settings.TaskDevicePluginConfigLong[event->TaskIndex][0] = getFormItemInt(F("plugin_002_adc1"));
Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = getFormItemFloat(F("plugin_002_out1"));
Settings.TaskDevicePluginConfigLong[event->TaskIndex][1] = getFormItemInt(F("plugin_002_adc2"));
Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = getFormItemFloat(F("plugin_002_out2"));
success = true;
break;
}
case PLUGIN_TEN_PER_SECOND:
{
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0]) //Oversampling?
{
Plugin_002_OversamplingValue += analogRead(A0);
Plugin_002_OversamplingCount ++;
}
success = true;
break;
}
case PLUGIN_READ:
{
int value = analogRead(A0);
UserVar[event->BaseVarIndex] = (float)value;
String log = F("ADC : Analog value: ");
log += value;
if (Plugin_002_OversamplingCount > 0)
{
UserVar[event->BaseVarIndex] = (float)Plugin_002_OversamplingValue / Plugin_002_OversamplingCount;
Plugin_002_OversamplingValue = 0;
Plugin_002_OversamplingCount = 0;
log += String(UserVar[event->BaseVarIndex], 3);
}
else
{
int16_t value = analogRead(A0);
UserVar[event->BaseVarIndex] = (float)value;
log += value;
}
if (Settings.TaskDevicePluginConfig[event->TaskIndex][3]) //Calibration?
{
int adc1 = Settings.TaskDevicePluginConfigLong[event->TaskIndex][0];
int adc2 = Settings.TaskDevicePluginConfigLong[event->TaskIndex][1];
float out1 = Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0];
float out2 = Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1];
if (adc1 != adc2)
{
float normalized = (float)(UserVar[event->BaseVarIndex] - adc1) / (float)(adc2 - adc1);
UserVar[event->BaseVarIndex] = normalized * (out2 - out1) + out1;
log += F(" = ");
log += String(UserVar[event->BaseVarIndex], 3);
}
}
addLog(LOG_LEVEL_INFO,log);
success = true;
break;
+12 -49
View File
@@ -64,22 +64,17 @@ boolean Plugin_003(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
char tmpString[128];
sprintf_P(tmpString, PSTR("<TR><TD>Debounce Time (mSec):<TD><input type='text' name='plugin_003' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
string += tmpString;
addFormNumericBox(string, 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];
options[0] = F("Delta");
options[1] = F("Delta/Total/Time");
options[2] = F("Total");
options[3] = F("Delta/Total");
int optionValues[4];
optionValues[0] = 0;
optionValues[1] = 1;
optionValues[2] = 2;
optionValues[3] = 3;
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 );
if (choice !=0)
string += F("<span style=\"color:red\">Total count is not persistent!</span>");
String modeRaise[4];
modeRaise[0] = F("LOW");
modeRaise[1] = F("CHANGE");
@@ -91,36 +86,7 @@ boolean Plugin_003(byte function, struct EventStruct *event, String& string)
modeValues[2] = RISING;
modeValues[3] = FALLING;
string += F("<TR><TD>Counter Type:<TD><select name='plugin_003_countertype'>");
for (byte x = 0; x < 4; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
if (choice !=0)
string += F("<span style=\"color:red\">Total count is not persistent!</span>");
string += F("<TR><TD>Counter Type:<TD><select name='plugin_003_raisetype'>");
for (byte x = 0; x < 4; x++)
{
string += F("<option value='");
string += modeValues[x];
string += "'";
if (choice2 == modeValues[x])
string += F(" selected");
string += ">";
string += modeRaise[x];
string += F("</option>");
}
string += F("</select>");
addFormSelector(string, F("Mode Type"), F("plugin_003_raisetype"), 4, modeRaise, modeValues, choice2 );
success = true;
break;
@@ -128,12 +94,9 @@ boolean Plugin_003(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg("plugin_003");
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
String plugin2 = WebServer.arg("plugin_003_countertype");
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin2.toInt();
String plugin3 = WebServer.arg("plugin_003_raisetype");
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = plugin3.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_003"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_003_countertype"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("plugin_003_raisetype"));
success = true;
break;
}
+484 -477
View File
File diff suppressed because it is too large Load Diff
+7 -26
View File
@@ -47,28 +47,10 @@ boolean Plugin_005(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[3];
options[0] = F("DHT 11");
options[1] = F("DHT 22");
options[2] = F("DHT 12");
int optionValues[3];
optionValues[0] = 11;
optionValues[1] = 22;
optionValues[2] = 12;
string += F("<TR><TD>DHT Type:<TD><select name='plugin_005_dhttype'>");
for (byte x = 0; x < 3; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
const String options[] = { F("DHT 11"), F("DHT 22"), F("DHT 12") };
int indices[] = { 11, 22, 12 };
addFormSelector(string, F("DHT Type"), F("plugin_005_dhttype"), 3, options, indices, Settings.TaskDevicePluginConfig[event->TaskIndex][0] );
success = true;
break;
@@ -76,8 +58,8 @@ boolean Plugin_005(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_005_dhttype"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_005_dhttype"));
success = true;
break;
}
@@ -132,7 +114,7 @@ boolean Plugin_005(byte function, struct EventStruct *event, String& string)
{
float temperature = NAN;
float humidity = NAN;
if (Par3 == 11)
{
temperature = float(dht_dat[2]); // Temperature
@@ -221,4 +203,3 @@ int Plugin_005_read_dht_dat(void)
//interrupts();
return result;
}
+4 -6
View File
@@ -8,6 +8,8 @@
#define PLUGIN_VALUENAME1_006 "Temperature"
#define PLUGIN_VALUENAME2_006 "Pressure"
// TODO this will not work if we have more than one of this task!
boolean Plugin_006_init = false;
boolean Plugin_006(byte function, struct EventStruct *event, String& string)
@@ -47,18 +49,14 @@ boolean Plugin_006(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
string += F("<TR><TD>Altitude [m]:<TD><input type='text' title='Set Altitude to 0 to get measurement without altitude adjustment' name='");
string += F("_p006_bmp085_elev' value='");
string += Settings.TaskDevicePluginConfig[event->TaskIndex][1];
string += F("'>");
addFormNumericBox(string, F("Altitude [m]"), F("_p006_bmp085_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
success = true;
break;
}
case PLUGIN_WEBFORM_SAVE:
{
String elev = WebServer.arg(F("_p006_bmp085_elev"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = elev.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("_p006_bmp085_elev"));
success = true;
break;
}
+84 -24
View File
@@ -7,15 +7,13 @@
#define PLUGIN_NAME_008 "RFID Reader - Wiegand"
#define PLUGIN_VALUENAME1_008 "Tag"
#define PLUGIN_008_WGSIZE 26
void Plugin_008_interrupt1() ICACHE_RAM_ATTR;
void Plugin_008_interrupt2() ICACHE_RAM_ATTR;
volatile byte Plugin_008_bitCount = 0; // Count the number of bits received.
volatile unsigned long Plugin_008_keyBuffer = 0; // A 32-bit-long keyBuffer into which the number is stored.
byte Plugin_008_bitCountPrev = 0; // to detect noise
byte Plugin_008_Unit = 0;
volatile byte Plugin_008_bitCount = 0; // Count the number of bits received.
uint64_t Plugin_008_keyBuffer = 0; // A 64-bit-long keyBuffer into which the number is stored.
byte Plugin_008_timeoutCount = 0;
byte Plugin_008_WiegandSize = 26; // size of a tag via wiegand (26-bits or 36-bits)
boolean Plugin_008_init = false;
@@ -52,10 +50,11 @@ boolean Plugin_008(byte function, struct EventStruct *event, String& string)
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_008));
break;
}
case PLUGIN_INIT:
{
Plugin_008_init = true;
Plugin_008_WiegandSize = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
pinMode(Settings.TaskDevicePin1[event->TaskIndex], INPUT_PULLUP);
pinMode(Settings.TaskDevicePin2[event->TaskIndex], INPUT_PULLUP);
attachInterrupt(Settings.TaskDevicePin1[event->TaskIndex], Plugin_008_interrupt1, FALLING);
@@ -68,31 +67,93 @@ boolean Plugin_008(byte function, struct EventStruct *event, String& string)
{
if (Plugin_008_init)
{
if ((Plugin_008_bitCount != PLUGIN_008_WGSIZE) && (Plugin_008_bitCount == Plugin_008_bitCountPrev))
if (Plugin_008_bitCount > 0)
{
// must be noise
Plugin_008_bitCount = 0;
if (Plugin_008_bitCount % 4 == 0 && ((Plugin_008_keyBuffer & 0xF) == 11))
{
// a number of keys were pressed and finished by #
Plugin_008_keyBuffer = Plugin_008_keyBuffer >> 4; // Strip #
UserVar[event->BaseVarIndex] = (Plugin_008_keyBuffer & 0xFFFF);
UserVar[event->BaseVarIndex + 1] = ((Plugin_008_keyBuffer >> 16) & 0xFFFF);
}
else if (Plugin_008_bitCount == Plugin_008_WiegandSize)
{
// read a tag
Plugin_008_keyBuffer = Plugin_008_keyBuffer >> 1; // Strip leading and trailing parity bits from the keyBuffer
if (Plugin_008_WiegandSize == 26)
Plugin_008_keyBuffer &= 0xFFFFFF;
else
Plugin_008_keyBuffer &= 0xFFFFFFFF;
UserVar[event->BaseVarIndex] = (Plugin_008_keyBuffer & 0xFFFF);
UserVar[event->BaseVarIndex + 1] = ((Plugin_008_keyBuffer >> 16) & 0xFFFF);
}
else
{
// not enough bits, maybe next time
Plugin_008_timeoutCount++;
if (Plugin_008_timeoutCount > 5)
{
String log = F("RFID : reset bits: ");
log += Plugin_008_bitCount;
addLog(LOG_LEVEL_INFO, log );
// reset after ~5 sec
Plugin_008_keyBuffer = 0;
Plugin_008_bitCount = 0;
Plugin_008_timeoutCount = 0;
}
break;
}
// reset everything
unsigned long bitCount = Plugin_008_bitCount; // copy for log
unsigned long keyBuffer = Plugin_008_keyBuffer; // copy for log
Plugin_008_keyBuffer = 0;
}
if (Plugin_008_bitCount == PLUGIN_008_WGSIZE)
{
Plugin_008_bitCount = 0; // Read in the current key and reset everything so that the interrupts can
Plugin_008_keyBuffer = Plugin_008_keyBuffer >> 1; // Strip leading and trailing parity bits from the keyBuffer
Plugin_008_keyBuffer &= 0xFFFFFF;
UserVar[event->BaseVarIndex] = (Plugin_008_keyBuffer & 0xFFFF);
UserVar[event->BaseVarIndex + 1] = ((Plugin_008_keyBuffer >> 16) & 0xFFFF);
Plugin_008_bitCount = 0;
Plugin_008_timeoutCount = 0;
// write log
String log = F("RFID : Tag: ");
log += Plugin_008_keyBuffer;
log += keyBuffer;
log += F(" Bits: ");
log += bitCount;
addLog(LOG_LEVEL_INFO, log);
sendData(event);
}
Plugin_008_bitCountPrev = Plugin_008_bitCount; // store this value for next check, detect noise
}
break;
}
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[2];
options[0] = F("26 Bits");
options[1] = F("34 Bits");
int optionValues[2];
optionValues[0] = 26;
optionValues[1] = 34;
string += F("<TR><TD>Wiegand Type:<TD><select name='plugin_008_type'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
success = true;
break;
}
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_008_type"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
success = true;
break;
}
}
return success;
}
@@ -115,4 +176,3 @@ void Plugin_008_interrupt2()
Plugin_008_keyBuffer = Plugin_008_keyBuffer << 1; // Left shift the number (effectively multiplying by 2)
Plugin_008_bitCount++; // Increment the bit count
}
+2 -8
View File
@@ -46,11 +46,7 @@ boolean Plugin_009(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
string += F("<TR><TD>Send Boot state:<TD>");
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0])
string += F("<input type=checkbox name=plugin_009_boot checked>");
else
string += F("<input type=checkbox name=plugin_009_boot>");
addFormCheckBox(string, F("Send Boot state") ,F("plugin_009_boot"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
success = true;
break;
@@ -58,9 +54,7 @@ boolean Plugin_009(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_009_boot"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = (plugin1 == "on");
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = isFormItemChecked(F("plugin_009_boot"));
success = true;
break;
+19 -46
View File
@@ -48,25 +48,16 @@ boolean Plugin_010(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
/*
String options[2];
options[0] = F("0x23 - default settings (ADDR Low)");
options[1] = F("0x5c - alternate settings (ADDR High)");
*/
int optionValues[2];
optionValues[0] = BH1750_DEFAULT_I2CADDR;
optionValues[1] = BH1750_SECOND_I2CADDR;
string += F("<TR><TD>I2C Address:<TD><select name='plugin_010'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
addFormSelectorI2C(string, F("plugin_010"), 2, optionValues, choice);
addFormNote(string, F("ADDR Low=0x23, High=0x5c"));
byte choiceMode = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String optionsMode[4];
@@ -79,25 +70,9 @@ boolean Plugin_010(byte function, struct EventStruct *event, String& string)
optionValuesMode[1] = RESOLUTION_NORMAL;
optionValuesMode[2] = RESOLUTION_HIGH;
optionValuesMode[3] = RESOLUTION_AUTO_HIGH;
string += F("<TR><TD>measurment mode:<TD><select name='plugin_010_mode'>");
for (byte x = 0; x < 4; x++)
{
string += F("<option value='");
string += optionValuesMode[x];
string += "'";
if (choiceMode == optionValuesMode[x])
string += F(" selected");
string += ">";
string += optionsMode[x];
string += F("</option>");
}
string += F("</select>");
addFormSelector(string, F("Measurment mode"), F("plugin_010_mode"), 4, optionsMode, optionValuesMode, choiceMode);
string += F("<TR><TD>Send sensor to sleep:<TD>");
if (Settings.TaskDevicePluginConfig[event->TaskIndex][2])
string += F("<input type=checkbox name=plugin_010_sleep checked>");
else
string += F("<input type=checkbox name=plugin_010_sleep>");
addFormCheckBox(string, F("Send sensor to sleep"), F("plugin_010_sleep"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
success = true;
break;
@@ -105,12 +80,9 @@ boolean Plugin_010(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_010"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
String plugin2 = WebServer.arg(F("plugin_010_mode"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin2.toInt();
String plugin3 = WebServer.arg(F("plugin_010_sleep"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = (plugin3 == "on");
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_010"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_010_mode"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = isFormItemChecked(F("plugin_010_sleep"));
success = true;
break;
}
@@ -122,14 +94,16 @@ boolean Plugin_010(byte function, struct EventStruct *event, String& string)
AS_BH1750 sensor = AS_BH1750(address);
sensors_resolution_t mode;
if (Settings.TaskDevicePluginConfig[event->TaskIndex][1]==RESOLUTION_LOW)
mode = RESOLUTION_LOW;
if (Settings.TaskDevicePluginConfig[event->TaskIndex][1]==RESOLUTION_NORMAL)
mode = RESOLUTION_NORMAL;
if (Settings.TaskDevicePluginConfig[event->TaskIndex][1]==RESOLUTION_HIGH)
mode = RESOLUTION_HIGH;
if (Settings.TaskDevicePluginConfig[event->TaskIndex][1]==RESOLUTION_AUTO_HIGH)
mode = RESOLUTION_AUTO_HIGH;
// replaced the 8 lines below to optimize code
mode = (sensors_resolution_t)Settings.TaskDevicePluginConfig[event->TaskIndex][1];
// if (Settings.TaskDevicePluginConfig[event->TaskIndex][1]==RESOLUTION_LOW)
// mode = RESOLUTION_LOW;
// if (Settings.TaskDevicePluginConfig[event->TaskIndex][1]==RESOLUTION_NORMAL)
// mode = RESOLUTION_NORMAL;
// if (Settings.TaskDevicePluginConfig[event->TaskIndex][1]==RESOLUTION_HIGH)
// mode = RESOLUTION_HIGH;
// if (Settings.TaskDevicePluginConfig[event->TaskIndex][1]==RESOLUTION_AUTO_HIGH)
// mode = RESOLUTION_AUTO_HIGH;
sensor.begin(mode,Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
@@ -150,4 +124,3 @@ boolean Plugin_010(byte function, struct EventStruct *event, String& string)
}
return success;
}
+3 -22
View File
@@ -46,25 +46,8 @@ boolean Plugin_011(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[2];
options[0] = F("Digital");
options[1] = F("Analog");
int optionValues[2];
optionValues[0] = 0;
optionValues[1] = 1;
string += F("<TR><TD>Port Type:<TD><select name='plugin_011'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
String options[2] = { F("Digital"), F("Analog") };
addFormSelector(string, F("Port Type"), F("plugin_011"), 2, options, NULL, choice);
success = true;
break;
@@ -72,8 +55,7 @@ boolean Plugin_011(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_011"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_011"));
success = true;
break;
}
@@ -229,4 +211,3 @@ boolean Plugin_011_Write(byte Par1, byte Par2)
Wire.write((Par2 >> 8));
Wire.endTransmission();
}
+11 -36
View File
@@ -55,47 +55,25 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
//String options[16];
int optionValues[16];
for (byte x = 0; x < 17; x++)
for (byte x = 0; x < 16; x++)
{
if (x < 8)
optionValues[x] = 0x20 + x;
else
optionValues[x] = 0x30 + x;
string += F("<TR><TD>I2C Address:<TD><select name='plugin_012_adr'>");
for (byte x = 0; x < 16; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += String(optionValues[x], HEX);
string += F("</option>");
//options[x] = F("0x");
//options[x] += String(optionValues[x], HEX);
}
string += F("</select>");
addFormSelectorI2C(string, F("plugin_012_adr"), 16, optionValues, choice);
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String options2[2];
options2[0] = F("2 x 16");
options2[1] = F("4 x 20");
int optionValues2[2];
optionValues2[0] = 1;
optionValues2[1] = 2;
string += F("<TR><TD>Display Size:<TD><select name='plugin_012_size'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues2[x];
string += "'";
if (choice2 == optionValues2[x])
string += F(" selected");
string += ">";
string += options2[x];
string += F("</option>");
}
string += F("</select>");
int optionValues2[2] = { 1, 2 };
addFormSelector(string, F("Display Size"), F("plugin_012_size"), 2, options2, optionValues2, choice2);
char deviceTemplate[4][80];
LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
@@ -124,12 +102,9 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_012_adr"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
String plugin2 = WebServer.arg(F("plugin_012_size"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin2.toInt();
String plugin3 = WebServer.arg(F("plugin_12_timer"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = plugin3.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_012_adr"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_012_size"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("plugin_12_timer"));
char deviceTemplate[4][80];
for (byte varNr = 0; varNr < 4; varNr++)
+11 -30
View File
@@ -30,7 +30,7 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 1;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
@@ -49,7 +49,7 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_013));
break;
}
case PLUGIN_WEBFORM_LOAD:
{
@@ -57,28 +57,12 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
String options[2];
options[0] = F("Value");
options[1] = F("State");
int optionValues[2];
optionValues[0] = 1;
optionValues[1] = 2;
string += F("<TR><TD>Mode:<TD><select name='plugin_013_mode'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
int optionValues[2] = { 1, 2 };
addFormSelector(string, F("Mode"), F("plugin_013_mode"), 2, options, optionValues, choice);
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 2)
{
char tmpString[128];
sprintf_P(tmpString, PSTR("<TR><TD>Threshold:<TD><input type='text' name='plugin_013_threshold' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
string += tmpString;
addFormNumericBox(string, F("Threshold"), F("plugin_013_threshold"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
}
success = true;
break;
@@ -86,12 +70,10 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_013_mode"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_013_mode"));
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 2)
{
String plugin2 = WebServer.arg(F("plugin_013_threshold"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin2.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_013_threshold"));
}
success = true;
break;
@@ -115,14 +97,14 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
Plugin_013_TRIG_Pin = Settings.TaskDevicePin1[event->TaskIndex];
float value = Plugin_013_read();
String log = F("SR04 : Distance: ");
if (value != -1)
if (value > 0)
{
UserVar[event->BaseVarIndex] = (float)Plugin_013_timer / 58;
UserVar[event->BaseVarIndex] = value;
log += UserVar[event->BaseVarIndex];
success = true;
}
else
log += F("SR04 : Distance: No reading!");
log += F("No reading!");
addLog(LOG_LEVEL_INFO,log);
}
@@ -136,7 +118,7 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
Plugin_013_TRIG_Pin = Settings.TaskDevicePin1[event->TaskIndex];
byte state = 0;
float value = Plugin_013_read();
if (value != -1)
if (value > 0)
{
if (value < Settings.TaskDevicePluginConfig[event->TaskIndex][1])
state = 1;
@@ -198,4 +180,3 @@ void Plugin_013_interrupt()
Plugin_013_timer = micros() - Plugin_013_timer;
}
}
+32 -45
View File
@@ -12,7 +12,7 @@
boolean Plugin_014_init = false;
// ======================================
// SI7021 sensor
// SI7021 sensor
// ======================================
#define SI7021_I2C_ADDRESS 0x40 // I2C address for the sensor
#define SI7021_MEASURE_TEMP_HUM 0xE0 // Measure Temp only after a RH conversion done
@@ -85,20 +85,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");
string += F("<TR><TD>Resolution (bits):<TD><select name='plugin_014_res'>");
for (byte x = 0; x < SI7021_RESOLUTION_OPTION; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
addFormSelector(string, F("Resolution"), F("plugin_014_res"), SI7021_RESOLUTION_OPTION, options, optionValues, choice);
//addUnit(string, F("bits"));
success = true;
break;
@@ -106,8 +94,7 @@ boolean Plugin_014(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_014_res"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_014_res"));
Plugin_014_init = false; // Force device setup next time
success = true;
break;
@@ -170,7 +157,7 @@ boolean Plugin_014_si7021_begin(uint8_t resolution)
ret = false;
}
return ret;
return ret;
}
/* ======================================================================
@@ -185,7 +172,7 @@ uint8_t Plugin_014_si7021_checkCRC(uint16_t data, uint8_t check)
uint32_t remainder, divisor;
//Pad with 8 bits because we have to add in the check value
remainder = (uint32_t)data << 8;
remainder = (uint32_t)data << 8;
// From: http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html
// POLYNOMIAL = 0x0131 = x^8 + x^5 + x^4 + 1 : http://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks
@@ -193,17 +180,17 @@ uint8_t Plugin_014_si7021_checkCRC(uint16_t data, uint8_t check)
divisor = (uint32_t) 0x988000;
// Add the check value
remainder |= check;
remainder |= check;
// Operate on only 16 positions of max 24.
// Operate on only 16 positions of max 24.
// The remaining 8 are our remainder and should be zero when we're done.
for (uint8_t i = 0 ; i < 16 ; i++) {
//Check if there is a one in the left position
if( remainder & (uint32_t)1<<(23 - i) )
if( remainder & (uint32_t)1<<(23 - i) )
remainder ^= divisor;
//Rotate the divisor max 16 times so that we have 8 bits left of a remainder
divisor >>= 1;
divisor >>= 1;
}
return ((uint8_t) remainder);
}
@@ -220,22 +207,22 @@ int8_t Plugin_014_si7021_readRegister(uint8_t * value)
// Request user register
Wire.beginTransmission(SI7021_I2C_ADDRESS);
Wire.write(SI7021_READ_REG);
Wire.write(SI7021_READ_REG);
Wire.endTransmission();
// request 1 byte result
// request 1 byte result
Wire.requestFrom(SI7021_I2C_ADDRESS, 1);
if (Wire.available()>=1) {
*value = Wire.read();
return 0;
}
return 1;
return 1;
}
/* ======================================================================
Function: Plugin_014_si7021_startConv
Purpose : return temperature or humidity measured
Purpose : return temperature or humidity measured
Input : data type SI7021_READ_HUM or SI7021_READ_TEMP
current config resolution
Output : 0 if okay
@@ -247,7 +234,7 @@ int8_t Plugin_014_si7021_startConv(uint8_t datatype, uint8_t resolution)
uint16_t raw ;
uint8_t checksum,tmp;
//Request a reading
//Request a reading
Wire.beginTransmission(SI7021_I2C_ADDRESS);
Wire.write(datatype);
Wire.endTransmission();
@@ -264,19 +251,19 @@ int8_t Plugin_014_si7021_startConv(uint8_t datatype, uint8_t resolution)
// So to be more safe, we add 5 ms to each and use 8,10,13,21 ms
// But for ESP Easy, I think it does not matter at all...
// Martinus is correct there was a bug Mesasure HUM need
// Martinus is correct there was a bug Mesasure HUM need
// hum+temp delay because it also measure temp
if (resolution == SI7021_RESOLUTION_11T_11RH)
tmp = 7;
else if (resolution == SI7021_RESOLUTION_12T_08RH)
tmp = 13;
else if (resolution == SI7021_RESOLUTION_13T_10RH)
tmp = 25;
else
else
tmp = 50;
// Humidity fire also temp measurment so delay
// Humidity fire also temp measurment so delay
// need to be increased by 2 if no Hold Master
if (datatype == SI7021_MEASURE_HUM)
tmp *=2;
@@ -286,14 +273,14 @@ int8_t Plugin_014_si7021_startConv(uint8_t datatype, uint8_t resolution)
/*
// Wait for data to become available, device will NACK during conversion
tmp = 0;
do
do
{
// Request device
Wire.beginTransmission(SI7021_I2C_ADDRESS);
//Wire.write(SI7021_READ_REG);
//Wire.write(SI7021_READ_REG);
error = Wire.endTransmission(true);
delay(1);
}
}
// always use time out in loop to avoid potential lockup (here 12ms max)
// https://www.silabs.com/Support%20Documents/TechnicalDocs/Si7021-A20.pdf page 5
while(error!=0 && tmp++<=12 );
@@ -310,12 +297,12 @@ int8_t Plugin_014_si7021_startConv(uint8_t datatype, uint8_t resolution)
// Check CRC of data received
if(Plugin_014_si7021_checkCRC(raw, checksum) != 0) {
addLog(LOG_LEVEL_INFO,F("SI7021 : checksum error!"));
return -1;
return -1;
}
// Humidity
// Humidity
if (datatype == SI7021_MEASURE_HUM || datatype == SI7021_MEASURE_HUM_HM) {
// Convert value to Himidity percent
// Convert value to Himidity percent
// pm-cz: it is possible to enable decimal places for humidity as well by multiplying the value in formula by 100
data = ((1250 * (long)raw) >> 16) - 60;
@@ -379,7 +366,7 @@ int8_t Plugin_014_si7021_readValues(uint8_t resolution)
/* ======================================================================
Function: Plugin_014_si7021_setResolution
Purpose : Sets the sensor resolution to one of four levels
Purpose : Sets the sensor resolution to one of four levels
Input : see #define default is SI7021_RESOLUTION_14T_12RH
Output : 0 if okay
Comments: -
@@ -393,16 +380,16 @@ int8_t Plugin_014_si7021_setResolution(uint8_t res)
error = Plugin_014_si7021_readRegister(&reg);
if ( error == 0) {
// remove resolution bits
reg &= SI7021_RESOLUTION_MASK ;
reg &= SI7021_RESOLUTION_MASK ;
// Prepare to write to the register value
Wire.beginTransmission(SI7021_I2C_ADDRESS);
Wire.write(SI7021_WRITE_REG);
Wire.write(SI7021_WRITE_REG);
// Write the new resolution bits but clear unused before
Wire.write(reg | ( res &= ~SI7021_RESOLUTION_MASK) );
Wire.write(reg | ( res &= ~SI7021_RESOLUTION_MASK) );
return (int8_t) Wire.endTransmission();
}
}
return error;
}
+13 -51
View File
@@ -327,28 +327,17 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
byte choice1 = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
/*
String options1[3];
options1[0] = F("0x39 - (default)");
options1[1] = F("0x49");
options1[2] = F("0x29");
*/
int optionValues1[3];
optionValues1[0] = TSL2561_ADDR;
optionValues1[1] = TSL2561_ADDR_1;
optionValues1[2] = TSL2561_ADDR_0;
string += F("<TR><TD>I2C Address:<TD><select name='plugin_015_tsl2561_i2c'>");
for (byte x = 0; x < 3; x++)
{
string += F("<option value='");
string += optionValues1[x];
string += "'";
if (choice1 == optionValues1[x])
string += F(" selected");
string += ">";
string += options1[x];
string += F("</option>");
}
string += F("</select>");
addFormSelectorI2C(string, F("plugin_015_tsl2561_i2c"), 3, optionValues1, choice1);
#define TSL2561_INTEGRATION_OPTION 3
@@ -361,32 +350,13 @@ 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);
string += F("<TR><TD>Integration time:<TD><select name='plugin_015_integration'>");
for (byte x = 0; x < TSL2561_INTEGRATION_OPTION; x++)
{
string += F("<option value='");
string += optionValues2[x];
string += "'";
if (choice2 == optionValues2[x])
string += F(" selected");
string += ">";
string += options2[x];
string += F("</option>");
}
string += F("</select>");
addFormCheckBox(string, F("Send sensor to sleep:"), F("plugin_015_sleep"),
Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
string += F("<TR><TD>Send sensor to sleep:<TD>");
if (Settings.TaskDevicePluginConfig[event->TaskIndex][2])
string += F("<input type=checkbox name=plugin_015_sleep checked>");
else
string += F("<input type=checkbox name=plugin_015_sleep>");
string += F("<TR><TD>Enable 16x Gain:<TD>");
if (Settings.TaskDevicePluginConfig[event->TaskIndex][3])
string += F("<input type=checkbox name=plugin_015_gain checked>");
else
string += F("<input type=checkbox name=plugin_015_gain>");
addFormCheckBox(string, F("Enable 16x Gain:"), F("plugin_015_gain"),
Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
success = true;
break;
@@ -394,17 +364,13 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_015_tsl2561_i2c"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_015_tsl2561_i2c"));
String plugin2 = WebServer.arg(F("plugin_015_integration"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin2.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_015_integration"));
String plugin3 = WebServer.arg(F("plugin_015_sleep"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = (plugin3 == "on");
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = isFormItemChecked(F("plugin_015_sleep"));
String plugin4 = WebServer.arg(F("plugin_015_gain"));
Settings.TaskDevicePluginConfig[event->TaskIndex][3] = (plugin4 == "on");
Settings.TaskDevicePluginConfig[event->TaskIndex][3] = isFormItemChecked(F("plugin_015_gain"));
success = true;
break;
@@ -429,7 +395,7 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
unsigned char time = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
plugin_015_setTiming(gain,time,ms);
plugin_015_setPowerUp();
delayMillis(ms);
delayBackground(ms);
unsigned int data0, data1;
if (plugin_015_getData(data0,data1))
@@ -475,7 +441,3 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
}
return success;
}
+1 -2
View File
@@ -66,8 +66,7 @@ boolean Plugin_017(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
string += F("<TR><TD>Reset Pin:<TD>");
addPinSelect(false, string, "taskdevicepin3", Settings.TaskDevicePin3[event->TaskIndex]);
addFormPinSelect(string, F("Reset Pin"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
success = true;
break;
}
+2 -8
View File
@@ -46,11 +46,7 @@ boolean Plugin_019(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
string += F("<TR><TD>Send Boot state:<TD>");
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0])
string += F("<input type=checkbox name=plugin_019_boot checked>");
else
string += F("<input type=checkbox name=plugin_019_boot>");
addFormCheckBox(string, F("Send Boot state"), F("plugin_019_boot"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
success = true;
break;
@@ -58,9 +54,7 @@ boolean Plugin_019(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_019_boot"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = (plugin1 == "on");
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = isFormItemChecked(F("plugin_019_boot"));
success = true;
break;
+16 -57
View File
@@ -45,13 +45,9 @@ boolean Plugin_020(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
char tmpString[128];
sprintf_P(tmpString, PSTR("<TR><TD>TCP Port:<TD><input type='text' name='plugin_020_port' value='%u'>"), ExtraTaskSettings.TaskDevicePluginConfigLong[0]);
string += tmpString;
sprintf_P(tmpString, PSTR("<TR><TD>Baud Rate:<TD><input type='text' name='plugin_020_baud' value='%u'>"), ExtraTaskSettings.TaskDevicePluginConfigLong[1]);
string += tmpString;
sprintf_P(tmpString, PSTR("<TR><TD>Data bits:<TD><input type='text' name='plugin_020_data' value='%u'>"), ExtraTaskSettings.TaskDevicePluginConfigLong[2]);
string += tmpString;
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]);
byte choice = ExtraTaskSettings.TaskDevicePluginConfigLong[3];
String options[3];
@@ -62,51 +58,21 @@ boolean Plugin_020(byte function, struct EventStruct *event, String& string)
optionValues[0] = 0;
optionValues[1] = 2;
optionValues[2] = 3;
string += F("<TR><TD>Parity:<TD><select name='plugin_020_parity'>");
for (byte x = 0; x < 3; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
addFormSelector(string, F("Parity"), F("plugin_020_parity"), 3, options, optionValues, choice);
sprintf_P(tmpString, PSTR("<TR><TD>Stop bits:<TD><input type='text' name='plugin_020_stop' value='%u'>"), ExtraTaskSettings.TaskDevicePluginConfigLong[4]);
string += tmpString;
addFormNumericBox(string, F("Stop bits"), F("plugin_020_stop"), ExtraTaskSettings.TaskDevicePluginConfigLong[4]);
string += F("<TR><TD>Reset target after boot:<TD>");
addPinSelect(false, string, "taskdevicepin1", Settings.TaskDevicePin1[event->TaskIndex]);
addFormPinSelect(string, 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]);
sprintf_P(tmpString, PSTR("<TR><TD>RX Receive Timeout (mSec):<TD><input type='text' name='plugin_020_rxwait' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
string += tmpString;
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String options2[3];
options2[0] = F("None");
options2[1] = F("Generic");
options2[2] = F("RFLink");
int optionValues2[3];
optionValues2[0] = 0;
optionValues2[1] = 1;
optionValues2[2] = 2;
string += F("<TR><TD>Event processing:<TD><select name='plugin_020_events'>");
for (byte x = 0; x < 3; x++)
{
string += F("<option value='");
string += optionValues2[x];
string += "'";
if (choice2 == optionValues2[x])
string += F(" selected");
string += ">";
string += options2[x];
string += F("</option>");
}
string += F("</select>");
addFormSelector(string, F("Event processing"), F("plugin_020_events"), 3, options2, NULL, choice2);
success = true;
break;
@@ -114,20 +80,13 @@ boolean Plugin_020(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_020_port"));
ExtraTaskSettings.TaskDevicePluginConfigLong[0] = plugin1.toInt();
String plugin2 = WebServer.arg(F("plugin_020_baud"));
ExtraTaskSettings.TaskDevicePluginConfigLong[1] = plugin2.toInt();
String plugin3 = WebServer.arg(F("plugin_020_data"));
ExtraTaskSettings.TaskDevicePluginConfigLong[2] = plugin3.toInt();
String plugin4 = WebServer.arg(F("plugin_020_parity"));
ExtraTaskSettings.TaskDevicePluginConfigLong[3] = plugin4.toInt();
String plugin5 = WebServer.arg(F("plugin_020_stop"));
ExtraTaskSettings.TaskDevicePluginConfigLong[4] = plugin5.toInt();
String plugin6 = WebServer.arg(F("plugin_020_rxwait"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin6.toInt();
String plugin7 = WebServer.arg(F("plugin_020_events"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin7.toInt();
ExtraTaskSettings.TaskDevicePluginConfigLong[0] = getFormItemInt(F("plugin_020_port"));
ExtraTaskSettings.TaskDevicePluginConfigLong[1] = getFormItemInt(F("plugin_020_baud"));
ExtraTaskSettings.TaskDevicePluginConfigLong[2] = getFormItemInt(F("plugin_020_data"));
ExtraTaskSettings.TaskDevicePluginConfigLong[3] = getFormItemInt(F("plugin_020_parity"));
ExtraTaskSettings.TaskDevicePluginConfigLong[4] = getFormItemInt(F("plugin_020_stop"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_020_rxwait"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_020_events"));
success = true;
break;
}
+7 -14
View File
@@ -53,12 +53,9 @@ boolean Plugin_021(byte function, struct EventStruct *event, String& string)
string += F("<TR><TD>Check Value:<TD>");
addTaskValueSelect(string, "plugin_021_value", Settings.TaskDevicePluginConfig[event->TaskIndex][1], Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
string += F("<TR><TD>Set Value:<TD><input type='text' name='plugin_021_setvalue' value='");
string += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0];
string += F("'>");
string += F("<TR><TD>Hysteresis:<TD><input type='text' name='plugin_021_hyst' value='");
string += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1];
string += F("'>");
addFormTextBox(string, F("Set Value"), 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);
LoadTaskSettings(event->TaskIndex); // we need to restore our original taskvalues!
success = true;
@@ -67,14 +64,10 @@ boolean Plugin_021(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_021_task"));
String plugin2 = WebServer.arg(F("plugin_021_value"));
String plugin3 = WebServer.arg(F("plugin_021_setvalue"));
String plugin4 = WebServer.arg(F("plugin_021_hyst"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin2.toInt();
Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = plugin3.toFloat();
Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = plugin4.toFloat();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_021_task"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_021_value"));
Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = getFormItemFloat(F("plugin_021_setvalue"));
Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = getFormItemFloat(F("plugin_021_hyst"));
success = true;
break;
}
+18 -80
View File
@@ -60,88 +60,30 @@ boolean Plugin_023(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[2];
options[0] = F("3C");
options[1] = F("3D");
int optionValues[2];
optionValues[0] = 0x3C;
optionValues[1] = 0x3D;
string += F("<TR><TD>I2C Address:<TD><select name='plugin_023_adr'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
/*String options[2] = { F("3C"), F("3D") };*/
int optionValues[2] = { 0x3C, 0x3D };
addFormSelectorI2C(string, F("plugin_023_adr"), 2, optionValues, choice);
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String options2[2];
options2[0] = F("Normal");
options2[1] = F("Rotated");
int optionValues2[2];
optionValues2[0] = 1;
optionValues2[1] = 2;
string += F("<TR><TD>Rotation:<TD><select name='plugin_023_rotate'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues2[x];
string += "'";
if (choice2 == optionValues2[x])
string += F(" selected");
string += ">";
string += options2[x];
string += F("</option>");
}
string += F("</select>");
String options2[2] = { F("Normal"), F("Rotated") };
int optionValues2[2] = { 1, 2 };
addFormSelector(string, F("Rotation"), F("plugin_023_rotate"), 2, options2, optionValues2, choice2);
byte choice3 = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
String options3[2];
options3[0] = F("128x64");
options3[1] = F("64x48");
int optionValues3[2];
optionValues3[0] = 1;
optionValues3[1] = 2;
string += F("<TR><TD>Display Size:<TD><select name='plugin_023_size'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues3[x];
string += "'";
if (choice3 == optionValues3[x])
string += F(" selected");
string += ">";
string += options3[x];
string += F("</option>");
}
string += F("</select>");
String options3[2] = { F("128x64"), F("64x48") };
int optionValues3[2] = { 1, 2 };
addFormSelector(string, F("Display Size"), F("plugin_023_size"), 2, options3, optionValues3, choice3);
char deviceTemplate[8][64];
LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
for (byte varNr = 0; varNr < 8; varNr++)
{
string += F("<TR><TD>Line ");
string += varNr + 1;
string += F(":<TD><input type='text' size='64' maxlength='64' name='Plugin_023_template");
string += varNr + 1;
string += F("' value='");
string += deviceTemplate[varNr];
string += F("'>");
addFormTextBox(string, String(F("Line ")) + (varNr + 1), String(F("Plugin_023_template")) + (varNr + 1), deviceTemplate[varNr], 64);
}
string += F("<TR><TD>Display button:<TD>");
addPinSelect(false, string, "taskdevicepin3", Settings.TaskDevicePin3[event->TaskIndex]);
addFormPinSelect(string, F("Display button"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
char tmpString[128];
sprintf_P(tmpString, PSTR("<TR><TD>Display Timeout:<TD><input type='text' name='plugin_23_timer' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
string += tmpString;
addFormNumericBox(string, F("Display Timeout"), F("plugin_23_timer"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
success = true;
break;
@@ -149,14 +91,10 @@ boolean Plugin_023(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_023_adr"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
String plugin2 = WebServer.arg(F("plugin_023_rotate"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin2.toInt();
String plugin3 = WebServer.arg(F("plugin_23_timer"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = plugin3.toInt();
String plugin4 = WebServer.arg(F("plugin_023_size"));
Settings.TaskDevicePluginConfig[event->TaskIndex][3] = plugin4.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_023_adr"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_023_rotate"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("plugin_23_timer"));
Settings.TaskDevicePluginConfig[event->TaskIndex][3] = getFormItemInt(F("plugin_023_size"));
char deviceTemplate[8][64];
for (byte varNr = 0; varNr < 8; varNr++)
@@ -482,7 +420,7 @@ static void Plugin_023_sendStr(unsigned char *string)
{
Plugin_023_SendChar(pgm_read_byte(Plugin_023_myFont[*string - 0x20] + i));
}
*string++;
string++;
}
}
@@ -499,7 +437,7 @@ static void Plugin_023_sendStrXY(const char *string, int X, int Y)
{
Plugin_023_SendChar(pgm_read_byte(Plugin_023_myFont[*string - 0x20] + i));
}
*string++;
string++;
}
}
+4 -17
View File
@@ -20,7 +20,7 @@ uint16_t readRegister024(uint8_t i2cAddress, uint8_t reg) {
ret = Wire.read(); // receive DATA
ret |= Wire.read() << 8; // receive DATA
uint8_t pec = Wire.read();
return ret;
return ret;
}
float readTemp024(uint8_t i2c_addr, uint8_t i2c_reg)
@@ -72,24 +72,12 @@ boolean Plugin_024(byte function, struct EventStruct *event, String& string)
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[MLX90614_OPTION];
uint optionValues[MLX90614_OPTION];
int optionValues[MLX90614_OPTION];
optionValues[0] = (0x07);
options[0] = F("IR object temperature");
optionValues[1] = (0x06);
options[1] = F("Ambient temperature");
string += F("<TR><TD>Option:<TD><select name='plugin_024_option'>");
for (byte x = 0; x < MLX90614_OPTION; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
addFormSelector(string, F("Option"), F("plugin_024_option"), MLX90614_OPTION, options, optionValues, choice);
success = true;
break;
@@ -97,8 +85,7 @@ boolean Plugin_024(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_024_option"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_024_option"));
Plugin_024_init = false; // Force device setup next time
success = true;
break;
+116 -97
View File
@@ -13,8 +13,9 @@ static uint16_t readRegister025(uint8_t i2cAddress, uint8_t reg) {
Wire.beginTransmission(i2cAddress);
Wire.write((0x00));
Wire.endTransmission();
Wire.requestFrom(i2cAddress, (uint8_t)2);
return ((Wire.read() << 8) | Wire.read());
if (Wire.requestFrom(i2cAddress, (uint8_t)2) != 2)
return 0x8000;
return ((Wire.read() << 8) | Wire.read());
}
boolean Plugin_025(byte function, struct EventStruct *event, String& string)
@@ -28,7 +29,7 @@ boolean Plugin_025(byte function, struct EventStruct *event, String& string)
Device[++deviceCount].Number = PLUGIN_ID_025;
Device[deviceCount].Type = DEVICE_TYPE_I2C;
Device[deviceCount].VType = SENSOR_TYPE_SINGLE;
Device[deviceCount].Ports = 4;
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
@@ -53,37 +54,59 @@ boolean Plugin_025(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
#define ADS1115_GAIN_OPTION 6
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[ADS1115_GAIN_OPTION];
uint optionValues[ADS1115_GAIN_OPTION];
optionValues[0] = (0x00);
options[0] = F("2/3x gain 6.144V 0.1875mV");
optionValues[1] = (0x02);
options[1] = F("1x gain 4.096V 0.125mV");
optionValues[2] = (0x04);
options[2] = F("2x gain 2.048V 0.0625mV");
optionValues[3] = (0x06);
options[3] = F("4x gain 1.024V 0.03125mV");
optionValues[4] = (0x08);
options[4] = F("8x gain 0.512V 0.015625mV");
optionValues[5] = (0x0A);
options[5] = F("16x gain 0.256V 0.0078125mV");
string += F("<TR><TD>Gain:<TD><select name='plugin_025_gain'>");
for (byte x = 0; x < ADS1115_GAIN_OPTION; x++)
byte port = Settings.TaskDevicePort[event->TaskIndex];
if (port > 0) //map old port logic to new gain and mode settings
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = Settings.TaskDevicePluginConfig[event->TaskIndex][0] / 2;
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = 0x48 + ((port-1)/4);
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = ((port-1) & 3) | 4;
Settings.TaskDevicePort[event->TaskIndex] = 0;
}
string += F("</select>");
#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);
addFormSubHeader(string, F("Input"));
#define ADS1115_PGA_OPTION 6
byte pga = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String pgaOptions[ADS1115_PGA_OPTION] = {
F("2/3x gain (FS=6.144V)"),
F("1x gain (FS=4.096V)"),
F("2x gain (FS=2.048V)"),
F("4x gain (FS=1.024V)"),
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);
#define ADS1115_MUX_OPTION 8
byte mux = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
String muxOptions[ADS1115_MUX_OPTION] = {
F("AIN0 - AIN1 (Differential)"),
F("AIN0 - AIN3 (Differential)"),
F("AIN1 - AIN3 (Differential)"),
F("AIN2 - AIN3 (Differential)"),
F("AIN0 - GND (Single-Ended)"),
F("AIN1 - GND (Single-Ended)"),
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);
addFormSubHeader(string, F("Two Point Calibration"));
addFormCheckBox(string, 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(" &#8793; ");
addTextBox(string, 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(" &#8793; ");
addTextBox(string, F("plugin_025_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
success = true;
break;
@@ -91,8 +114,20 @@ boolean Plugin_025(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_025_gain"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_025_i2c"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_025_gain"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("plugin_025_mode"));
Settings.TaskDevicePluginConfig[event->TaskIndex][3] = isFormItemChecked(F("plugin_025_cal"));
Settings.TaskDevicePluginConfigLong[event->TaskIndex][0] = getFormItemInt(F("plugin_025_adc1"));
Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = getFormItemFloat(F("plugin_025_out1"));
Settings.TaskDevicePluginConfigLong[event->TaskIndex][1] = getFormItemInt(F("plugin_025_adc2"));
Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = getFormItemFloat(F("plugin_025_out2"));
Plugin_025_init = false; // Force device setup next time
success = true;
break;
@@ -107,76 +142,60 @@ boolean Plugin_025(byte function, struct EventStruct *event, String& string)
case PLUGIN_READ:
{
uint8_t m_gain = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
int value;
value = 0;
byte unit = (Settings.TaskDevicePort[event->TaskIndex] - 1) / 4;
byte port = Settings.TaskDevicePort[event->TaskIndex] - (unit * 4);
uint8_t address = 0x48 + unit;
// get the current pin value
//int value = 0;
//byte unit = (Settings.TaskDevicePort[event->TaskIndex] - 1) / 4;
//byte port = Settings.TaskDevicePort[event->TaskIndex] - (unit * 4);
//uint8_t address = 0x48 + unit;
uint16_t config = (0x0003) | // Disable the comparator (default val)
(0x0000) | // Non-latching (default val)
(0x0000) | // Alert/Rdy active low (default val)
(0x0000) | // Traditional comparator (default val)
(0x0080) | // 1600 samples per second (default)
(0x0100) ; // Single-shot mode (default)
uint8_t address = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
uint16_t config = (0x0003) | // Disable the comparator (default val)
(0x0000) | // Non-latching (default val)
(0x0000) | // Alert/Rdy active low (default val)
(0x0000) | // Traditional comparator (default val)
(0x0080) | // 128 samples per second (default)
(0x0100); // Single-shot mode (default)
uint16_t pga = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
config |= pga << 9;
uint16_t mux = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
config |= mux << 12;
config |= (0x8000); // Start a single conversion
// m_Gain = (0x0000); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default)
// m_Gain = (0x0200); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV
// m_Gain = (0x0400); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV
// m_Gain = (0x0600); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV
// m_Gain = (0x0800); // 8x gain +/- 0.512V 1 bit = 0.25mV 0.015625mV
// m_Gain = (0x0A00); // 16x gain +/- 0.256V 1 bit = 0.125mV 0.0078125mV
// config |= m_gain;
// config |= (0x0000);
switch (m_gain)
{
case (0x00):
config |= (0x0000);
break;
case (0x02):
config |= (0x0200);
break;
case (0x04):
config |= (0x0400);
break;
case (0x06):
config |= (0x0600);
break;
case (0x08):
config |= (0x0800);
break;
case (0x0A):
config |= (0x0A00);
break;
}
switch (port)
{
case (1):
config |= (0x4000);
break;
case (2):
config |= (0x5000);
break;
case (3):
config |= (0x6000);
break;
case (4):
config |= (0x7000);
break;
}
config |= (0x8000);
Wire.beginTransmission(address);
Wire.write((uint8_t)(0x01));
Wire.write((uint8_t)(config>>8));
Wire.write((uint8_t)(config >> 8));
Wire.write((uint8_t)(config & 0xFF));
Wire.endTransmission();
String log = F("ADS1115 : Analog value: ");
delay(8);
UserVar[event->BaseVarIndex] = (float) readRegister025((address), (0x00)) ;
String log = F("ADS1115 : Analog value: ");
log += UserVar[event->BaseVarIndex];
addLog(LOG_LEVEL_INFO,log);
int16_t value = readRegister025((address), (0x00));
UserVar[event->BaseVarIndex] = (float)value;
log += value;
if (Settings.TaskDevicePluginConfig[event->TaskIndex][3]) //Calibration?
{
int adc1 = Settings.TaskDevicePluginConfigLong[event->TaskIndex][0];
int adc2 = Settings.TaskDevicePluginConfigLong[event->TaskIndex][1];
float out1 = Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0];
float out2 = Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1];
if (adc1 != adc2)
{
float normalized = (float)(value - adc1) / (float)(adc2 - adc1);
UserVar[event->BaseVarIndex] = normalized * (out2 - out1) + out1;
log += F(" ");
log += UserVar[event->BaseVarIndex];
}
}
//TEST log += F(" @0x");
//TEST log += String(config, 16);
addLog(LOG_LEVEL_DEBUG,log);
success = true;
break;
}
+30 -25
View File
@@ -1,5 +1,5 @@
//#######################################################################################################
//#################################### Plugin 026: Analog ###############################################
//#################################### Plugin 026: System Info ##########################################
//#######################################################################################################
#define PLUGIN_026
@@ -40,31 +40,17 @@ boolean Plugin_026(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[5];
String options[9];
options[0] = F("Uptime");
options[1] = F("Free RAM");
options[2] = F("Wifi RSSI");
options[3] = F("Input VCC");
options[4] = F("System load");
int optionValues[5];
optionValues[0] = 0;
optionValues[1] = 1;
optionValues[2] = 2;
optionValues[3] = 3;
optionValues[4] = 4;
string += F("<TR><TD>Indicator:<TD><select name='plugin_026'>");
for (byte x = 0; x < 5; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
options[5] = F("IP 1.Octet");
options[6] = F("IP 2.Octet");
options[7] = F("IP 3.Octet");
options[8] = F("IP 4.Octet");
addFormSelector(string, F("Indicator"), F("plugin_026"), 9, options, NULL, choice);
success = true;
break;
@@ -72,12 +58,11 @@ boolean Plugin_026(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_026"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_026"));
success = true;
break;
}
case PLUGIN_READ:
{
float value = 0;
@@ -111,7 +96,27 @@ boolean Plugin_026(byte function, struct EventStruct *event, String& string)
{
value = (100 - (100 * loopCounterLast / loopCounterMax));
break;
}
}
case 5:
{
value = WiFi.localIP()[0];
break;
}
case 6:
{
value = WiFi.localIP()[1];
break;
}
case 7:
{
value = WiFi.localIP()[2];
break;
}
case 8:
{
value = WiFi.localIP()[3];
break;
}
}
UserVar[event->BaseVarIndex] = value;
String log = F("SYS : ");
+96 -74
View File
@@ -6,6 +6,8 @@
#define PLUGIN_ID_027 27
#define PLUGIN_NAME_027 "Voltage & Current (DC) - INA219"
#define PLUGIN_VALUENAME1_027 "Voltage"
#define PLUGIN_VALUENAME2_027 "Current"
#define PLUGIN_VALUENAME3_027 "Power"
#define INA219_ADDRESS (0x40) // 1000000 (A0+A1=GND)
#define INA219_ADDRESS2 (0x41) // 1000000 (A0+A1=GND)
@@ -77,13 +79,13 @@ boolean Plugin_027(byte function, struct EventStruct *event, String& string)
{
Device[++deviceCount].Number = PLUGIN_ID_027;
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].SendDataOption = false;
Device[deviceCount].ValueCount = 3;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].GlobalSyncOption = true;
break;
@@ -98,62 +100,35 @@ boolean Plugin_027(byte function, struct EventStruct *event, String& string)
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_027));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_027));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_027));
break;
}
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[3];
options[0] = F("Voltage");
options[1] = F("Current");
options[2] = F("Power");
int optionValues[3];
optionValues[0] = 0;
optionValues[1] = 1;
optionValues[2] = 2;
string += F("<TR><TD>Report:<TD><select name='plugin_027_value'>");
for (byte x = 0; x < 3; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
byte choiceMode = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String optionsMode[3];
optionsMode[0] = F("32V, 2A");
optionsMode[1] = F("32V, 1A");
optionsMode[2] = F("16V, 0.4A");
int optionValuesMode[3];
optionValuesMode[0] = 0;
optionValuesMode[1] = 1;
optionValuesMode[2] = 2;
addFormSelector(string, F("Measure range"), F("plugin_027_range"), 3, optionsMode, optionValuesMode, choiceMode);
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String options2[4];
options2[0] = F("0x40 - (default)");
options2[1] = F("0x41");
options2[2] = F("0x44");
options2[3] = F("0x45");
int optionValues2[3];
int optionValues2[4];
optionValues2[0] = INA219_ADDRESS;
optionValues2[1] = INA219_ADDRESS2;
optionValues2[2] = INA219_ADDRESS3;
optionValues2[3] = INA219_ADDRESS4;
string += F("<TR><TD>I2C Address:<TD><select name='plugin_027_i2c'>");
for (byte x = 0; x < 4; x++)
{
string += F("<option value='");
string += optionValues2[x];
string += "'";
if (choice2 == optionValues2[x])
string += F(" selected");
string += ">";
string += options2[x];
string += F("</option>");
}
string += F("</select>");
addFormSelectorI2C(string, F("plugin_027_i2c"), 4, optionValues2, choice2);
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 );
success = true;
break;
@@ -161,11 +136,9 @@ boolean Plugin_027(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_027_value"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
String plugin2 = WebServer.arg(F("plugin_027_i2c"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin2.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_027_range"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_027_i2c"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("plugin_027_measuretype"));
success = true;
break;
}
@@ -173,7 +146,31 @@ boolean Plugin_027(byte function, struct EventStruct *event, String& string)
case PLUGIN_INIT:
{
ina219_i2caddr = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
Plugin_027_begin();
ina219_currentDivider_mA = 0;
switch (Settings.TaskDevicePluginConfig[event->TaskIndex][0])
{
case 0:
{
addLog(LOG_LEVEL_INFO, F("INA219 setting Range to: 32V, 2A"));
Plugin_027_setCalibration_32V_2A();
break;
}
case 1:
{
addLog(LOG_LEVEL_INFO, F("INA219 setting Range to: 32V, 1A"));
Plugin_027_setCalibration_32V_1A();
break;
}
case 2:
{
addLog(LOG_LEVEL_INFO, F("INA219 setting Range to: 16V, 400mA"));
Plugin_027_setCalibration_16V_400mA();
break;
}
}
success = true;
break;
}
@@ -184,29 +181,66 @@ boolean Plugin_027(byte function, struct EventStruct *event, String& string)
// busvoltage = Plugin_027_getBusVoltage_V();
// current_mA = Plugin_027_getCurrent_mA();
// loadvoltage = Plugin_027_getBusVoltage_V() + (Plugin_027_getShuntVoltage_mV() / 1000);
float value=0;
switch(Settings.TaskDevicePluginConfig[event->TaskIndex][0])
float voltage = Plugin_027_getBusVoltage_V() + (Plugin_027_getShuntVoltage_mV() / 1000);
float current = Plugin_027_getCurrent_mA()/1000;
float power = (Plugin_027_getBusVoltage_V() + (Plugin_027_getShuntVoltage_mV() / 1000)) * Plugin_027_getCurrent_mA() / 1000;
UserVar[event->BaseVarIndex] = voltage;
UserVar[event->BaseVarIndex + 1] = current;
UserVar[event->BaseVarIndex + 2] = power;
String log = F("INA219 0x");
log += String(ina219_i2caddr,HEX);
// for backward compability we allow the user to select if only one measurement should be returned
// or all 3 measurement at once
switch (Settings.TaskDevicePluginConfig[event->TaskIndex][2])
{
case 0:
{
value = Plugin_027_getBusVoltage_V() + (Plugin_027_getShuntVoltage_mV() / 1000);
event->sensorType = SENSOR_TYPE_SINGLE;
UserVar[event->BaseVarIndex] = voltage;
log += F(": Voltage: ");
log += voltage;
break;
}
case 1:
{
value = Plugin_027_getCurrent_mA()/1000;
event->sensorType = SENSOR_TYPE_SINGLE;
UserVar[event->BaseVarIndex] = current;
log += F(" Current: ");
log += current;
break;
}
case 2:
{
value = (Plugin_027_getBusVoltage_V() + (Plugin_027_getShuntVoltage_mV() / 1000)) * Plugin_027_getCurrent_mA() / 1000;
event->sensorType = SENSOR_TYPE_SINGLE;
UserVar[event->BaseVarIndex] = power;
log += F(" Power: ");
log += power;
break;
}
case 3:
{
event->sensorType = SENSOR_TYPE_TRIPLE;
UserVar[event->BaseVarIndex] = voltage;
UserVar[event->BaseVarIndex+1] = current;
UserVar[event->BaseVarIndex+2] = power;
log += F(": Voltage: ");
log += voltage;
log += F(" Current: ");
log += current;
log += F(" Power: ");
log += power;
break;
}
}
UserVar[event->BaseVarIndex] = value;
String log = F("INA : value: ");
log += value;
addLog(LOG_LEVEL_INFO,log);
addLog(LOG_LEVEL_INFO, log);
success = true;
break;
}
@@ -311,17 +345,6 @@ void Plugin_027_setCalibration_16V_400mA(void) {
}
//**************************************************************************/
// Setups the HW (defaults to 32V and 2A for calibration values)
//**************************************************************************/
void Plugin_027_begin(void) {
ina219_currentDivider_mA = 0;
// Set chip to large range config values to start
Plugin_027_setCalibration_32V_2A();
}
//**************************************************************************/
// Gets the raw bus voltage (16-bit signed integer, so +-32767)
//**************************************************************************/
@@ -386,4 +409,3 @@ float Plugin_027_getCurrent_mA() {
valueDec /= ina219_currentDivider_mA;
return valueDec;
}
+12 -27
View File
@@ -124,29 +124,17 @@ boolean Plugin_028(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
/*
String options[2];
options[0] = F("0x76 - default settings (SDO Low)");
options[1] = F("0x77 - alternate settings (SDO HIGH)");
int optionValues[2];
optionValues[0] = 0x76;
optionValues[1] = 0x77;
string += F("<TR><TD>I2C Address:<TD><select name='plugin_028_bme280_i2c'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
string += F("<TR><TD>Altitude [m]:<TD><input type='text' title='Set Altitude to 0 to get measurement without altitude adjustment' name='");
string += F("plugin_028_bme280_elev' value='");
string += Settings.TaskDevicePluginConfig[event->TaskIndex][1];
string += F("'>");
*/
int optionValues[2] = { 0x76, 0x77 };
addFormSelectorI2C(string, F("plugin_028_bme280_i2c"), 2, optionValues, choice);
addFormNote(string, F("SDO Low=0x76, High=0x77"));
addFormNumericBox(string, F("Altitude"), F("plugin_028_bme280_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addUnit(string, F("m"));
success = true;
break;
@@ -154,10 +142,8 @@ boolean Plugin_028(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_028_bme280_i2c"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
String elev = WebServer.arg(F("plugin_028_bme280_elev"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = elev.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_028_bme280_i2c"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_028_bme280_elev"));
success = true;
break;
}
@@ -228,14 +214,14 @@ bool Plugin_028_begin(uint8_t a) {
return false;
Plugin_028_readCoefficients(_i2caddr & 0x01);
// Set the Sensor in sleep to be make sure that the following configs will be stored
Plugin_028_write8(BME280_REGISTER_CONTROL, 0x00);
Plugin_028_write8(BME280_REGISTER_CONFIG, BME280_CONFIG_SETTING);
Plugin_028_write8(BME280_REGISTER_CONTROLHUMID, BME280_CONTROL_SETTING_HUMIDITY);
Plugin_028_write8(BME280_REGISTER_CONTROL, BME280_CONTROL_SETTING);
return true;
}
@@ -462,4 +448,3 @@ float Plugin_028_readAltitude(float seaLevel)
float Plugin_028_pressureElevation(float atmospheric, int altitude) {
return atmospheric / pow(1.0 - (altitude/44330.0), 5.255);
}
+18
View File
@@ -39,6 +39,24 @@ boolean Plugin_029(byte function, struct EventStruct *event, String& string)
break;
}
case PLUGIN_WEBFORM_LOAD:
{
// We need the index of the controller we are: 0-CONTROLLER_MAX
byte controllerNr = 0;
for (byte i=0; i < CONTROLLER_MAX; i++)
{
// if (Settings.Protocol[i] == CPLUGIN_ID_002) { controllerNr = i; } -> error: 'CPLUGIN_ID_002' was not declared in this scope
if (Settings.Protocol[i] == 2) { controllerNr = i; }
}
string += F("<TR><TD>IDX:<TD>");
String id = F("TDID"); //="taskdeviceid"
id += controllerNr + 1;
addNumericBox(string, id, Settings.TaskDeviceID[controllerNr][event->TaskIndex], 0, 9999);
success = true;
break;
}
case PLUGIN_INIT:
{
success = true;
+9 -28
View File
@@ -103,29 +103,13 @@ boolean Plugin_030(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[2];
options[0] = F("0x76 - default settings (SDO Low)");
options[1] = F("0x77 - alternate settings (SDO HIGH)");
int optionValues[2];
optionValues[0] = 0x76;
optionValues[1] = 0x77;
string += F("<TR><TD>I2C Address:<TD><select name='plugin_030_bmp280_i2c'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
string += F("<TR><TD>Altitude [m]:<TD><input type='text' title='Set Altitude to 0 to get measurement without altitude adjustment' name='");
string += F("plugin_030_bmp280_elev' value='");
string += Settings.TaskDevicePluginConfig[event->TaskIndex][1];
string += F("'>");
/*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"));
addFormNumericBox(string, F("Altitude"), F("plugin_030_bmp280_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addUnit(string, F("m"));
success = true;
break;
@@ -133,10 +117,8 @@ boolean Plugin_030(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_030_bmp280_i2c"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
String elev = WebServer.arg(F("plugin_030_bmp280_elev"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = elev.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_030_bmp280_i2c"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_030_bmp280_elev"));
success = true;
break;
}
@@ -412,4 +394,3 @@ float Plugin_030_readAltitude(float seaLevel)
float Plugin_030_pressureElevation(float atmospheric, int altitude) {
return atmospheric / pow(1.0 - (altitude/44330.0), 5.255);
}
+20 -41
View File
@@ -70,29 +70,11 @@ boolean Plugin_032(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[2];
options[0] = F("0x77 - default I2C address");
options[1] = F("0x76 - alternate I2C address");
int optionValues[2];
optionValues[0] = 0x77;
optionValues[1] = 0x76;
string += F("<TR><TD>I2C Address:<TD><select name='plugin_032_ms5611_i2c'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
string += F("<TR><TD>Altitude [m]:<TD><input type='text' title='Set Altitude to 0 to get measurement without altitude adjustment' name='");
string += F("plugin_032_ms5611_elev' value='");
string += Settings.TaskDevicePluginConfig[event->TaskIndex][1];
string += F("'>");
/*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);
addFormNumericBox(string, F("Altitude [m]"), F("plugin_032_ms5611_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
success = true;
break;
@@ -100,10 +82,8 @@ boolean Plugin_032(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_032_ms5611_i2c"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
String elev = WebServer.arg(F("plugin_032_ms5611_elev"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = elev.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_032_ms5611_i2c"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_032_ms5611_elev"));
success = true;
break;
}
@@ -112,13 +92,13 @@ boolean Plugin_032(byte function, struct EventStruct *event, String& string)
{
if (!Plugin_032_init)
{
Plugin_032_init = Plugin_032_begin(Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
Plugin_032_init = Plugin_032_begin(Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
}
if (Plugin_032_init) {
Plugin_032_read_prom();
Plugin_032_readout();
UserVar[event->BaseVarIndex] = ms5611_temperature / 100;
int elev = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
if (elev)
@@ -167,9 +147,9 @@ byte Plugin_032_send_cmd(byte aCMD)
//**************************************************************************/
// Reads the PROM of MS5611
// There are in total 8 addresses resulting in a total memory of 128 bit.
// Address 0 contains factory data and the setup, addresses 1-6 calibration
// coefficients and address 7 contains the serial code and CRC.
// There are in total 8 addresses resulting in a total memory of 128 bit.
// Address 0 contains factory data and the setup, addresses 1-6 calibration
// coefficients and address 7 contains the serial code and CRC.
// The command sequence is 8 bits long with a 16 bit result which is
// clocked with the MSB first.
//**************************************************************************/
@@ -177,7 +157,7 @@ void Plugin_032_read_prom() {
Plugin_032_send_cmd(MS5xxx_CMD_RESET);
delay(3);
for(uint8_t i=0;i<8;i++)
for(uint8_t i=0;i<8;i++)
{
ms5611_prom[i]=0x0000;
Plugin_032_send_cmd(MS5xxx_CMD_PROM_RD+2*i);
@@ -188,7 +168,7 @@ void Plugin_032_read_prom() {
c = Wire.read();
ms5611_prom[i] += c;
Wire.endTransmission(true);
}
}
}
//**************************************************************************/
@@ -198,7 +178,7 @@ unsigned long Plugin_032_read_adc(unsigned char aCMD)
{
unsigned long value=0;
unsigned long c=0;
Plugin_032_send_cmd(MS5xxx_CMD_ADC_CONV+aCMD); // start DAQ and conversion of ADC data
switch (aCMD & 0x0f)
{
@@ -222,7 +202,7 @@ unsigned long Plugin_032_read_adc(unsigned char aCMD)
c = Wire.read();
value += c;
Wire.endTransmission(true);
return value;
}
@@ -233,7 +213,7 @@ unsigned long Plugin_032_read_adc(unsigned char aCMD)
void Plugin_032_readout() {
unsigned long D1=0, D2=0;
double dT;
double OFF;
double SENS;
@@ -247,7 +227,7 @@ void Plugin_032_readout() {
SENS=ms5611_prom[1]*pow(2,15)+dT*ms5611_prom[3]/pow(2,8);
ms5611_temperature=(2000+(dT*ms5611_prom[6])/pow(2,23));
ms5611_pressure=(((D1*SENS)/pow(2,21)-OFF)/pow(2,15));
// perform higher order corrections
double T2=0., OFF2=0., SENS2=0.;
if(ms5611_temperature<2000) {
@@ -259,11 +239,11 @@ void Plugin_032_readout() {
SENS2+=11*(ms5611_temperature+1500)*(ms5611_temperature+1500)/pow(2,1);
}
}
ms5611_temperature-=T2;
OFF-=OFF2;
SENS-=SENS2;
ms5611_pressure=(((D1*SENS)/pow(2,21)-OFF)/pow(2,15));
ms5611_pressure=(((D1*SENS)/pow(2,21)-OFF)/pow(2,15));
}
//**************************************************************************/
@@ -272,4 +252,3 @@ void Plugin_032_readout() {
double Plugin_032_pressureElevation(double atmospheric, int altitude) {
return atmospheric / pow(1.0 - (altitude/44330.0), 5.255);
}
+4 -17
View File
@@ -69,19 +69,8 @@ boolean Plugin_033(byte function, struct EventStruct *event, String& string)
optionValues[8] = SENSOR_TYPE_DIMMER;
optionValues[9] = SENSOR_TYPE_LONG;
optionValues[10] = SENSOR_TYPE_WIND;
string += F("<TR><TD>Simulate Data Type:<TD><select name='plugin_033_sensortype'>");
for (byte x = 0; x < 11; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
addFormSelector(string, F("Simulate Data Type"), F("plugin_033_sensortype"), 11, options, optionValues, choice );
success = true;
break;
@@ -89,12 +78,11 @@ boolean Plugin_033(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg(F("plugin_033_sensortype"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_033_sensortype"));
success = true;
break;
}
case PLUGIN_READ:
{
event->sensorType = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
@@ -112,4 +100,3 @@ boolean Plugin_033(byte function, struct EventStruct *event, String& string)
}
return success;
}
+39 -6
View File
@@ -59,7 +59,7 @@ boolean Plugin_035(byte function, struct EventStruct *event, String& string)
String IrType;
unsigned long IrCode;
unsigned int IrBits;
char log[120];
//char log[120];
char command[120];
command[0] = 0;
@@ -82,9 +82,9 @@ boolean Plugin_035(byte function, struct EventStruct *event, String& string)
if (IrType.equalsIgnoreCase("RAW")) {
String IrRaw;
unsigned int IrHz;
unsigned int IrPLen;
unsigned int IrBLen;
unsigned int IrHz=0;
unsigned int IrPLen=0;
unsigned int IrBLen=0;
if (GetArgv(command, TmpStr1, 3)) IrRaw = TmpStr1;
if (GetArgv(command, TmpStr1, 4)) IrHz = str2int(TmpStr1);
@@ -109,44 +109,77 @@ boolean Plugin_035(byte function, struct EventStruct *event, String& string)
unsigned int buf[200];
unsigned int idx = 0;
unsigned int c0 = 0;
unsigned int c1 = 0;
unsigned int c0 = 0; //count consecutives 0s
unsigned int c1 = 0; //count consecutives 1s
printWebString += F("Interpreted RAW Code: ");
//Loop throught every char in RAW string
for(int i = 0; i < IrRaw.length(); i++)
{
//Get the decimal value from base32 table
//See: https://en.wikipedia.org/wiki/Base32#base32hex
char c = ((IrRaw[i] | ('A' ^ 'a')) - '0') % 39;
//Loop through 5 LSB (bits 16, 8, 4, 2, 1)
for (unsigned int shft = 1; shft < 6; shft++)
{
//if bit is 1 (5th position - 00010000 = 16)
if ((c & 16) != 0) {
//add 1 to counter c1
c1++;
//if we already have any 0s in counting (the previous
//bit was 0)
if (c0 > 0) {
//add the total ms into the buffer (number of 0s multiplied
//by defined blank length ms)
buf[idx++] = c0 * IrBLen;
//print the number of 0s just for debuging/info purpouses
for (uint t = 0; t < c0; t++)
printWebString += F("0");
}
//So, as we recieve a "1", and processed the counted 0s
//sending them as a ms timing into the buffer, we clear
//the 0s counter
c0 = 0;
} else {
//So, bit is 0
//On first call, ignore 0s (supress left-most 0s)
if (c0+c1 != 0) {
//add 1 to counter c0
c0++;
//if we already have any 1s in counting (the previous
//bit was 1)
if (c1 > 0) {
//add the total ms into the buffer (number of 1s
//multiplied by defined pulse length ms)
buf[idx++] = c1 * IrPLen;
//print the number of 1s just for debuging/info purpouses
for (uint t = 0; t < c1; t++)
printWebString += F("1");
}
//So, as we recieve a "0", and processed the counted 1s
//sending them as a ms timing into the buffer, we clear
//the 1s counter
c1 = 0;
}
}
//shift to left the "c" variable to process the next bit that is
//in 5th position (00010000 = 16)
c <<= 1;
}
}
//Finally, we need to process the last counted bit that we were
//processing
//If we have pendings 0s
if (c0 > 0) {
buf[idx] = c0 * IrBLen;
for (uint t = 0; t < c0; t++)
printWebString += F("0");
}
//If we have pendings 1s
if (c1 > 0) {
buf[idx] = c1 * IrPLen;
for (uint t = 0; t < c1; t++)
+16 -91
View File
@@ -69,48 +69,22 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
byte choice0 = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
/*
String options0[2];
options0[0] = F("3C");
options0[1] = F("3D");
*/
int optionValues0[2];
optionValues0[0] = 0x3C;
optionValues0[1] = 0x3D;
string += F("<TR><TD>I2C Address:<TD><select name='plugin_036_adr'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues0[x];
string += "'";
if (choice0 == optionValues0[x])
string += F(" selected");
string += ">";
string += options0[x];
string += F("</option>");
}
string += F("</select>");
//
addFormSelectorI2C(string, 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];
optionValues1[0] = 1;
optionValues1[1] = 2;
string += F("<TR><TD>Rotation:<TD><select name='plugin_036_rotate'>");
for (byte x = 0; x < 2; x++)
{
string += F("<option value='");
string += optionValues1[x];
string += "'";
if (choice1 == optionValues1[x])
string += F(" selected");
string += ">";
string += options1[x];
string += F("</option>");
}
string += F("</select>");
int optionValues1[2] = { 1, 2 };
addFormSelector(string, F("Rotation"), F("plugin_036_rotate"), 2, options1, optionValues1, choice1);
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
String options2[4];
@@ -118,24 +92,8 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
options2[1] = F("2");
options2[2] = F("3");
options2[3] = F("4");
int optionValues2[4];
optionValues2[0] = 1;
optionValues2[1] = 2;
optionValues2[2] = 3;
optionValues2[3] = 4;
string += F("<TR><TD>Lines per Frame:<TD><select name='plugin_036_nlines'>");
for (byte x = 0; x < 4; x++)
{
string += F("<option value='");
string += optionValues2[x];
string += "'";
if (choice2 == optionValues2[x])
string += F(" selected");
string += ">";
string += options2[x];
string += F("</option>");
}
string += F("</select>");
int optionValues2[4] = { 1, 2, 3, 4 };
addFormSelector(string, F("Lines per Frame"), F("plugin_036_nlines"), 4, options2, optionValues2, choice2);
byte choice3 = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
String options3[5];
@@ -150,42 +108,19 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
optionValues3[2] = 4;
optionValues3[3] = 8;
optionValues3[4] = 32;
string += F("<TR><TD>Scroll:<TD><select name='plugin_036_scroll'>");
for (byte x = 0; x < 5; x++)
{
string += F("<option value='");
string += optionValues3[x];
string += F("'");
if (choice3 == optionValues3[x])
string += F(" selected");
string += F(">");
string += options3[x];
string += F("</option>");
}
string += F("</select>");
addFormSelector(string, F("Scroll"), F("plugin_036_scroll"), 5, options3, optionValues3, choice3);
char deviceTemplate[Nlines][32];
LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
for (byte varNr = 0; varNr < Nlines; varNr++)
{
string += F("<TR><TD>Line ");
string += varNr + 1;
string += F(":<TD><input type='text' size='32' maxlength='32' name='Plugin_036_template");
string += varNr + 1;
string += F("' value='");
string += deviceTemplate[varNr];
string += F("'>");
addFormTextBox(string, String(F("Line ")) + (varNr + 1), String(F("Plugin_036_template")) + (varNr + 1), deviceTemplate[varNr], 32);
}
string += F("<TR><TD>Display button:<TD>");
addPinSelect(false, string, "taskdevicepin3", Settings.TaskDevicePin3[event->TaskIndex]);
addFormPinSelect(string, F("Display button"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
char tmpString[128];
sprintf_P(tmpString, PSTR("<TR><TD>Display Timeout:<TD><input type='text' name='plugin_036_timer' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][4]);
string += tmpString;
addFormNumericBox(string, F("Display Timeout"), F("plugin_036_timer"), Settings.TaskDevicePluginConfig[event->TaskIndex][4]);
success = true;
break;
@@ -193,21 +128,11 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
String plugin0 = WebServer.arg(F("plugin_036_adr"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin0.toInt();
String plugin1 = WebServer.arg(F("plugin_036_rotate"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin1.toInt();
String plugin2 = WebServer.arg(F("plugin_036_nlines"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = plugin2.toInt();
String plugin3 = WebServer.arg(F("plugin_036_scroll"));
Settings.TaskDevicePluginConfig[event->TaskIndex][3] = plugin3.toInt();
String plugin4 = WebServer.arg(F("plugin_036_timer"));
Settings.TaskDevicePluginConfig[event->TaskIndex][4] = plugin4.toInt();
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_036_adr"));
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_036_rotate"));
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("plugin_036_nlines"));
Settings.TaskDevicePluginConfig[event->TaskIndex][3] = getFormItemInt(F("plugin_036_scroll"));
Settings.TaskDevicePluginConfig[event->TaskIndex][4] = getFormItemInt(F("plugin_036_timer"));
String argName;

Some files were not shown because too many files have changed in this diff Show More