Compare commits

...
Author SHA1 Message Date
ESPEasy release bot e1e894d540 automaticly updated release notes for mega-20180304 2018-03-04 04:00:08 +01:00
Unknown d15311e70a Merge branch 'v2.0' into mega 2018-03-04 00:50:43 +01:00
Gijs NoorlanderandGitHub 3ed6564063 [issue #892 ] Only use sensor type when really needed (#1004)
[issue #892 ] Only use sensor type when really needed
2018-03-04 00:45:52 +01:00
Unknown 5f575c0224 [issue #892 ] Only use sensor type when really needed
Only the Domoticz controllers need the sensor type. The rest just needs the number of sensor values.
2018-03-04 00:37:18 +01:00
Gijs NoorlanderandGitHub 34c1ba158f [issue #993] Add %unit% variable in MQTT subscribe topic (PR #1002)
[issue #993] Add %unit% variable in MQTT subscribe topic
2018-03-03 22:40:18 +01:00
Unknown 04ca424085 [issue #993] Add %unit% variable in MQTT subscribe topic 2018-03-03 22:39:09 +01:00
Gijs Noorlander 7a8f476e05 _P072_HDC1080 allow to send values to the controllers (#999)
_P072_HDC1080 add success and break statement.
it seems that without the break statement and success set to true, the values aren't sent back to the controller(s).
2018-03-03 21:30:22 +01:00
Gijs NoorlanderandGitHub eef8391ffc _P072_HDC1080 allow to send values to the controllers (#999)
_P072_HDC1080 add success and break statement.
it seems that without the break statement and success set to true, the values aren't sent back to the controller(s).
2018-03-03 21:29:12 +01:00
Gijs NoorlanderandGitHub d47751c31f Fixes P073 plugin for latest TM1637 based 7 segments displays modules (#996)
Fixes P073 plugin for latest TM1637 based 7 segments displays modules
2018-03-03 20:40:11 +01:00
Gijs Noorlander e42ab85f4b Merge pull request #1000 from uzi18/test3 (more comparisions in IF condition)
support for more comparisions in IF condition: >=,<=,!=,<>,<,>,= also fix extended conditions when first check is not '>'
2018-03-03 20:38:13 +01:00
Gijs NoorlanderandGitHub b048d3f1f8 Merge pull request #1000 from uzi18/test3 (more comparisions in IF condition)
support for more comparisions in IF condition: >=,<=,!=,<>,<,>,= also fix extended conditions when first check is not '>'
2018-03-03 20:37:07 +01:00
Bartlomiej Zimon f94ab3a04a - support for more comparisions in IF conditions: >=,<=,!=,<>,<,>,=
also fix extended conditions when first check is not >
2018-03-03 16:04:44 +01:00
mvdbro 1b9375f83b ESP32 Dallas DS18B20 fix
This is a quick fix for this sensor only. It seems that ESP32 RTOS needs more or differtent interrupt handling for time critical sensor code.
2018-03-03 14:08:20 +01:00
clumsy-stefanandGitHub a77798d18f add success and break statement
it seems that without the break statement and success set to true, the values aren ot sent back to the controller(s).
2018-03-03 13:05:25 +01:00
ESPEasy release bot 3094cb5260 automaticly updated release notes for v2.0-20180303 2018-03-03 04:00:19 +01:00
ESPEasy release bot ec4dd09968 automaticly updated release notes for mega-20180303 2018-03-03 04:00:08 +01:00
Unknown d68a5fb9d4 Merge branch 'v2.0' into mega 2018-03-03 02:23:03 +01:00
Gijs NoorlanderandGitHub 0e67480f46 Merge pull request #995 from TD-er/bugfix/mqtt_proper_case
Bugfix/mqtt proper case
2018-03-03 02:19:49 +01:00
Unknown c32f2cc89d Add AND/OR to rules & prevent unwanted case changes in strings (#994) 2018-03-03 02:09:41 +01:00
Unknown ad489f0db2 [Issue #827] MQTT not using proper case for %sysname% variable.
Some functions and plugins could change strings to lowercase.
Added some check also to help debugging.
2018-03-03 02:03:20 +01:00
Gijs NoorlanderandGitHub d9267fa9c2 Add Task device type to json by @s0170071 (#991)
Add Task device type to json by @s0170071
2018-03-02 22:40:20 +01:00
Unknown e82fb37870 Add Task device type to json by @s0170071
Taken from his branch, he forgot to PR.
2018-03-02 22:30:55 +01:00
Unknown 635c149f12 Merge branch 'v2.0' into mega 2018-03-02 22:16:37 +01:00
Gijs NoorlanderandGitHub 26f00dcdec [issue #293] json output nan values not double quoted (#990)
[issue #293] json output nan values not double quoted
2018-03-02 22:03:07 +01:00
Unknown b2bb1d039b [issue #293] json output nan values not double quoted
Generate valid JSON output
2018-03-02 21:49:06 +01:00
soif 57e256a5fa Fixes P073 plugin for latest TM1637 based 7 segments displays modules 2018-03-02 21:06:45 +01:00
Unknown c58e975b7e revert json to non-chunking #988 from s0170071/mega
revert json to non-chunking
2018-03-02 20:40:13 +01:00
Gijs NoorlanderandGitHub 7d16ffa4a4 revert json to non-chunking #988 from s0170071/mega
revert json to non-chunking
2018-03-02 20:36:42 +01:00
s0170071 856e370ba0 make handle_json return void 2018-03-02 15:00:48 +01:00
s0170071 4df9e7d065 Add git build and local time 2018-03-02 13:58:05 +01:00
s0170071 edb3857e04 revert json to non-chunking 2018-03-02 13:17:20 +01:00
ESPEasy release bot 08312cbcb7 automaticly updated release notes for v2.0-20180302 2018-03-02 04:00:21 +01:00
ESPEasy release bot fb1cc219ee automaticly updated release notes for mega-20180302 2018-03-02 04:00:10 +01:00
Unknown da7329891d Merge branch 'v2.0' into mega 2018-03-02 02:08:55 +01:00
Gijs NoorlanderandGitHub 953a53bb9a Merge pull request #985 from TD-er/bugfix/json_content-length
backport of "rule wildcard" + improve formatting of Webserver's StreamingBuffer
2018-03-02 01:58:53 +01:00
Unknown e9fac7926f [webserver] Layout of code to improve readability
Indentation was completely off, which made it hard to read.
Also added member json_format, which is set at start of stream.
2018-03-02 01:53:40 +01:00
mvdbroandUnknown 810a0b2aa9 Rule wildcard option on literal events
Added wildcard rule filter on literal string events
Changed "sendcontent free"content logging level to 'DEV'
2018-03-01 23:41:42 +01:00
Unknown 7f897bc856 Merge branch 'v2.0' into mega
Merge initiated from GitKraken directly on Letscontrol_it/ESPEasy
2018-03-01 23:31:00 +01:00
Gijs NoorlanderandGitHub 5d9137d1d2 Merge pull request #976 from TD-er/bugfix/P053_PMSx003DustPlugin
[issue #914] _P053_PMSx003 Dust Sensor looses sync
2018-03-01 23:07:38 +01:00
Gijs Noorlander 8de49cd38e Merge pull request #983 from kahvm/mega
Added support for degree sign on LCD1602/2004
2018-03-01 22:42:58 +01:00
Gijs NoorlanderandGitHub 0092ba92b5 Merge pull request #983 from kahvm/mega
Added support for degree sign on LCD1602/2004
2018-03-01 22:41:54 +01:00
Gijs NoorlanderandGitHub fe1c44f6b3 Merge pull request #980 from uzi18/formatout
Format output marge from mega to v2.0
2018-03-01 22:34:08 +01:00
Gijs NoorlanderandGitHub e39d588530 Merge pull request #975 from TD-er/merge/important_fixes_from_mega
Merge/important fixes from mega
2018-03-01 22:31:36 +01:00
kahvmandGitHub 7a4e3d954d Merge pull request #1 from kahvm/support-degree-sign-lcd1602
Support for degree sign on LCD1602
2018-03-01 22:00:41 +01:00
kahvmandGitHub 9dc4fefa0b Support for degree sign on LCD1602
More: https://www.letscontrolit.com/forum/viewtopic.php?p=11875#p11875
2018-03-01 20:09:50 +01:00
Unknown 4ca318f5a6 [Build error fix] Must-keep-focus-when-pressing-buttons...
Quickly commit + merge is never a good idea when some visitors arrive...
Fixed now.
2018-03-01 20:08:51 +01:00
mvdbro 695bb58d64 Rule wildcard option on literal events
Added wildcard rule filter on literal string events
Changed "sendcontent free"content logging level to 'DEV'
2018-03-01 14:29:10 +01:00
Bartlomiej Zimon 608a7212eb Merge branch 'mega' of github.com:letscontrolit/ESPEasy into test3 2018-03-01 03:02:23 +01:00
Bartłomiej ZimońandBartlomiej Zimon 37a24933f5 add format #O to templates to show OFF/ON instead 0/1 (#949)
* - pcfgpio,port,2 sets pin as input
- fix for #222,#702 - we can mix inputs and outputs now

* - extend conditions with AND/OR, now it is possible to simplify rules

test rules:
on test do
  if [test#a]=0 or [test#b]=0 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test2 do
  if [test#a]=1 and [test#b]=1 and [test#c]=1
    event ok
  else
    event nok
  endif
endon

on test3 do
  if [test#a]=1 and [test#b]=1 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test4 do
  if [test#a]=0
    event ok
  else
    event nok
  endif
endon

* - remove Serial print

* - add format #O to templates to show OFF/ON instead 0/1 - eg.: Pump:[Outputs#pump#O]

* - add formating for active low outputs eg.: #O!
2018-02-28 23:06:01 +01:00
Bartlomiej Zimon a6b447600f Merge branch 'v2.0' of github.com:letscontrolit/ESPEasy into v2.0 2018-02-28 22:43:52 +01:00
Unknown 5fbb900e5b [issue #914] Check first 2 bytes of packet 2018-02-28 22:39:34 +01:00
ESPEasy release bot aa5dee01fb automaticly updated release notes for v2.0-20180228 2018-02-28 04:00:20 +01:00
ESPEasy release bot 4e2a5d3b3d automaticly updated release notes for mega-20180228 2018-02-28 04:00:09 +01:00
Unknown 1a44ed6578 [issue #914] _P053_PMSx003 Dust Sensor looses sync
- Use peek instead of read, to make sure a complete packet is in the buffer.
- Flush buffer after processing a packet.
- Increased software serial buffer to the size of 3 packets.
- Peek (+ read garbage) 10 times per second to get the buffer in sync to start with start byte of packet.
- Decent delete + clean up of software serial allocation when changing settings (prevent memory leak)
- Move log String allocation to inside scope of function, not permanent allocated.
- Split into separate functions to make it better readable.
2018-02-28 02:11:33 +01:00
Bartłomiej ZimońandUnknown e86667e37e fix #964, add timeStringToSeconds and use it to compare time conditions (#965)
* - pcfgpio,port,2 sets pin as input
- fix for #222,#702 - we can mix inputs and outputs now

* - extend conditions with AND/OR, now it is possible to simplify rules

test rules:
on test do
  if [test#a]=0 or [test#b]=0 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test2 do
  if [test#a]=1 and [test#b]=1 and [test#c]=1
    event ok
  else
    event nok
  endif
endon

on test3 do
  if [test#a]=1 and [test#b]=1 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test4 do
  if [test#a]=0
    event ok
  else
    event nok
  endif
endon

* - remove Serial print

* - add format #O to templates to show OFF/ON instead 0/1 - eg.: Pump:[Outputs#pump#O]

* - add formating for active low outputs eg.: #O!

* - fix #964, add timeStringToSeconds and use it to compare time conditions

* - fix number of pages available to browse
2018-02-28 00:00:37 +01:00
s0170071andUnknown 0db1f78421 Add Factory Reset button to web interface (#954) 2018-02-27 23:59:31 +01:00
Bartłomiej ZimońandUnknown 780c34846e add format #O to templates to show OFF/ON instead 0/1 (#949)
* - pcfgpio,port,2 sets pin as input
- fix for #222,#702 - we can mix inputs and outputs now

* - extend conditions with AND/OR, now it is possible to simplify rules

test rules:
on test do
  if [test#a]=0 or [test#b]=0 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test2 do
  if [test#a]=1 and [test#b]=1 and [test#c]=1
    event ok
  else
    event nok
  endif
endon

on test3 do
  if [test#a]=1 and [test#b]=1 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test4 do
  if [test#a]=0
    event ok
  else
    event nok
  endif
endon

* - remove Serial print

* - add format #O to templates to show OFF/ON instead 0/1 - eg.: Pump:[Outputs#pump#O]

* - add formating for active low outputs eg.: #O!
2018-02-27 23:58:50 +01:00
Edwin Eefting a4dcc304a9 Merge branch 'v2.0' into mega 2018-02-27 23:43:36 +01:00
Gijs NoorlanderandDatuX a938bc78c1 [issue #968] Use template parser for OLED commands (#974)
N.B. Now even task values can be used in commands, next to special characters.
2018-02-27 23:43:18 +01:00
Gijs NoorlanderandDatuX d2c7743197 [issue #966] Add %sysweekday% and %sysweekday_s% (#973)
- %sysweekday%  number of the day (Sunday = 1)
- %sysweekday_s%  3 letter String of the weekday (Sun, Mon, Tue, ...)
2018-02-27 23:43:01 +01:00
Bartłomiej ZimońandDatuX f0fc20de57 fix #964, add timeStringToSeconds and use it to compare time conditions (#965)
* - pcfgpio,port,2 sets pin as input
- fix for #222,#702 - we can mix inputs and outputs now

* - extend conditions with AND/OR, now it is possible to simplify rules

test rules:
on test do
  if [test#a]=0 or [test#b]=0 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test2 do
  if [test#a]=1 and [test#b]=1 and [test#c]=1
    event ok
  else
    event nok
  endif
endon

on test3 do
  if [test#a]=1 and [test#b]=1 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test4 do
  if [test#a]=0
    event ok
  else
    event nok
  endif
endon

* - remove Serial print

* - add format #O to templates to show OFF/ON instead 0/1 - eg.: Pump:[Outputs#pump#O]

* - add formating for active low outputs eg.: #O!

* - fix #964, add timeStringToSeconds and use it to compare time conditions

* - fix number of pages available to browse
2018-02-27 23:42:20 +01:00
ESPEasy release bot d35a50be17 automaticly updated release notes for v2.0-20180227 2018-02-27 04:00:22 +01:00
ESPEasy release bot 537d4cd1e9 automaticly updated release notes for mega-20180227 2018-02-27 04:00:11 +01:00
Edwin Eefting 62422f4924 Merge branch 'v2.0' into mega 2018-02-27 00:42:15 +01:00
Edwin Eefting 04de145dbb [test suite] changes from mega to 2.0 2018-02-27 00:41:27 +01:00
Edwin Eefting 21840d0b26 [test suite] changes from mega to 2.0 2018-02-27 00:41:21 +01:00
Gijs NoorlanderandDatuX 076ce0127b [build conflict] Renamed ESP32 version of ping (#963)
Had a conflict with the ESP8266 version of ping.
Let's hope I did not break anything with the ESP32 builds @mvdbro does.
2018-02-27 00:10:17 +01:00
Edwin Eefting 226c0a6f83 Merge branch 'v2.0' into mega 2018-02-26 23:03:48 +01:00
s0170071andDatuX 6ffa8d92a6 Add Factory Reset button to web interface (#954) 2018-02-26 22:54:24 +01:00
Bartłomiej ZimońandDatuX dae2cc2f4a add format #O to templates to show OFF/ON instead 0/1 (#949)
* - pcfgpio,port,2 sets pin as input
- fix for #222,#702 - we can mix inputs and outputs now

* - extend conditions with AND/OR, now it is possible to simplify rules

test rules:
on test do
  if [test#a]=0 or [test#b]=0 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test2 do
  if [test#a]=1 and [test#b]=1 and [test#c]=1
    event ok
  else
    event nok
  endif
endon

on test3 do
  if [test#a]=1 and [test#b]=1 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test4 do
  if [test#a]=0
    event ok
  else
    event nok
  endif
endon

* - remove Serial print

* - add format #O to templates to show OFF/ON instead 0/1 - eg.: Pump:[Outputs#pump#O]

* - add formating for active low outputs eg.: #O!
2018-02-26 22:53:15 +01:00
Gijs NoorlanderandDatuX 555ccbe229 [BuildError] StreamingBuffer code cleanup + fix order member initialize (#961)
The order in which the members are defined should also be the order in which they will be initialized.

Also applied #958
2018-02-26 22:52:27 +01:00
mvdbro d277d22914 Fix ESP32 compile errors 2018-02-26 14:26:17 +01:00
ESPEasy release bot b5e4994392 automaticly updated release notes for v2.0-20180226 2018-02-26 04:00:21 +01:00
ESPEasy release bot cbdddf8c06 automaticly updated release notes for mega-20180226 2018-02-26 04:00:08 +01:00
Gijs NoorlanderandGitHub 8b5d22a081 Merge pull request #948 from TD-er/build/remove_duplicate_library
[softwareSerial] Remove duplicate with only capilization as difference
2018-02-25 21:29:09 +01:00
Unknown 88fc0a8445 [softwareSerial] Remove duplicate with only capilization as difference 2018-02-25 21:27:57 +01:00
Gijs NoorlanderandGitHub ec9187d038 Merge pull request #947 from letscontrolit/v2.0
V2.0 => Mega: Ping library and Webserver@LowMemory
2018-02-25 21:20:37 +01:00
s0170071andUnknown 51ede17d2a Update WebServer.ino 2018-02-25 21:15:33 +01:00
s0170071andUnknown 97ee69b371 V20 Webserver@LowMemory 2018-02-25 21:15:24 +01:00
Unknown f77ce9c8f7 [ping lib] Added ping library
It was linked as a dependency in PlatformIO.ini, but apparently will add complexity to Arduino IDE users.
2018-02-25 21:14:07 +01:00
Edwin Eefting 99cc6f72af Merge branch 'v2.0' into mega 2018-02-25 17:18:59 +01:00
Gijs NoorlanderandDatuX 848f43b704 [2k Webserver] Proper initialisation of StreamingBuffer members. (#941)
Was reported in Travis as build error.
2018-02-25 17:17:47 +01:00
Edwin Eefting 3a5ef5da81 device page doesnt need next/previous page buttons anymore 2018-02-25 17:12:45 +01:00
Edwin Eefting 3527b69718 Merge branch 'v2.0' into mega 2018-02-25 16:57:03 +01:00
Gijs NoorlanderandDatuX 54628bfca9 [timeouts] Improve response when hosts are not reachable (#939)
See #922 and #847

Problem with DNS resolve is that it is quite slow when resulting in a failure and it tends to keep the ESP occupied and make it unresponsive.

Changed the way it is connecting to a controller.
Not sure if http requests are still OK, maybe we should make an exception for those when selected to use DNS.
2018-02-25 14:15:56 +01:00
Gijs NoorlanderandDatuX 72ff745eff [Mega] rename SoftwareSerial lib #930 (#937)
Just a rename of the library directory + some notes in the library description to indicate the differences.
2018-02-25 14:12:59 +01:00
Gijs NoorlanderandDatuX aed566b6db [v2.0] Use ESPeasySoftwareSerial (#936)
This one has virtual destructor and will use less memory.
See issue #930.
2018-02-25 14:12:33 +01:00
Gijs NoorlanderandDatuX 504ea0c813 [v2.0 merge] 2kwebserver_merge_to_mega #929 (#934)
The v2.0 branch merge of the 2k webserver PR.
As test build, please try [these builds](https://www.dropbox.com/s/ky6ldixh6wgzd8k/2k_webserver_build_v2.0_20180221.rar?dl=0)
2018-02-25 14:12:11 +01:00
Gijs NoorlanderandDatuX 4ca5ef3f72 [v2.0] Added Vcc-binaries to deploy process #933 (#935)
PR for the V2.0 branch to add the VCC binaries to the deploy process.
2018-02-25 14:11:34 +01:00
Michael SchröderandDatuX dd9db3b557 Added Vcc-binaries to deploy process (#933) 2018-02-25 14:11:25 +01:00
Bartłomiej ZimońandDatuX 9c531b30bc - extend conditions with AND/OR, now it is possible to simplify rules (#932)
* - pcfgpio,port,2 sets pin as input
- fix for #222,#702 - we can mix inputs and outputs now

* - extend conditions with AND/OR, now it is possible to simplify rules

test rules:
on test do
  if [test#a]=0 or [test#b]=0 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test2 do
  if [test#a]=1 and [test#b]=1 and [test#c]=1
    event ok
  else
    event nok
  endif
endon

on test3 do
  if [test#a]=1 and [test#b]=1 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test4 do
  if [test#a]=0
    event ok
  else
    event nok
  endif
endon

* - remove Serial print
2018-02-25 14:04:55 +01:00
Bartłomiej ZimońandDatuX 67c8477a61 provide System@Sleep event (#875) (#931)
- provide System@Sleep event
- fixes #870 (mqtt not sent before sleep)
- call deepsleep at the end of loop - so we know all is done
2018-02-25 14:01:40 +01:00
Edwin Eefting cd30b81202 Merge branch '2kwebservermergetomega' of https://github.com/s0170071/ESPEasy into mega 2018-02-25 13:55:28 +01:00
s0170071andDatuX 550881faa5 Memtracker (#927)
* preparations for lwip2

* Add CRC32 to settings

* Add CRC to progmem

* Add crc of program memory to stettings and security settings

.. so that there is a warning if the settings are used by another binary than they were written with.

* Moved to md5

* Flash included, moved to MD5 now

* Broken comment

* Stability improvements

free memory went as low as 3000 bytes which made the webserver unresponsive.

* Add binary filename to crc2.py and sysinfo

* Update WebServer.ino

* Memory tracker

displays debug memory trace

WD   : Uptime 3 ConnectFailures 0 FreeMem 15304
Memtrace
0: lowest: 4456  PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 handle_hardware-> 15192 sendWebPage-> 9672 sendWebPageChunkedData-> 5816 sendWebPageChunkedData-> 5128 sendWebPageChunkedData-> 4456 sendWebPageChunkedData-> 4456 
1: lowest: 4456  PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 handle_hardware-> 15192 sendWebPage-> 9672 sendWebPageChunkedData-> 5816 sendWebPageChunkedData-> 5128 sendWebPageChunkedData-> 4456 
2: lowest: 3768  PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 PluginCall_s (35)-> 15328 handle_hardware-> 15192 sendWebPage-> 9672 sendWebPageChunkedData-> 5816 sendWebPageChunkedData-> 5128 sendWebPageChunkedData-> 4456 sendWebPageChunkedData-> 4456 sendWebPageChunkedData-> 3768 
WD   : Uptime 4 ConnectFailures 0 FreeMem 15304

* Update Misc.ino
2018-02-25 13:14:57 +01:00
Gijs NoorlanderandDatuX 3d07466904 [MQTT] LWT "Connected" message doesn't have the retained flag (#925)
See comments of [Superpiffer](https://github.com/letscontrolit/ESPEasy/commit/a93a078c0b8ae4090c22717eacc8bc8ba92ad780#commitcomment-27718045)
2018-02-25 13:10:58 +01:00
s0170071 ed45945f21 Fix compile error when SD card is enabled 2018-02-24 18:03:38 +01:00
s0170071 f13abe8922 Removed double entry on info page 2018-02-24 17:32:44 +01:00
s0170071 34b0a683a9 fix travis 2018-02-24 17:10:52 +01:00
s0170071 9ab10437b5 Merge remote-tracking branch 's0170071/2kwebservermergetomega' into 2kwebservermergetomega 2018-02-24 16:59:54 +01:00
s0170071 b0b7408522 variable timeout 2018-02-24 16:59:46 +01:00
s0170071 b104942db9 Merge remote-tracking branch 's0170071/2kwebservermergetomega' into 2kwebservermergetomega 2018-02-24 16:57:17 +01:00
s0170071 a694b658b1 Merge remote-tracking branch 's0170071/2kwebservermergetomega' into 2kwebservermergetomega 2018-02-24 16:57:07 +01:00
s0170071 cb07a0d342 Merge remote-tracking branch 's0170071/2kwebservermergetomega' into 2kwebservermergetomega 2018-02-24 16:54:06 +01:00
s0170071 1ceaad04ec Merge branch '2kws_dynpayload' into 2kwebservermergetomega 2018-02-24 16:53:56 +01:00
s0170071 5cbf0c1e38 Merge branch '2kws_dynpayload' into 2kwebservermergetomega 2018-02-24 16:48:14 +01:00
Bartlomiej Zimon 4951f294b9 - remove Serial print 2018-02-24 16:34:30 +01:00
s0170071 ef0ef092f0 Merge remote-tracking branch 's0170071/2kws_dynpayload' into 2kws_dynpayload 2018-02-24 16:24:44 +01:00
s0170071ands0170071 46d3ae6a2b Merge branch 'mega' into 2kwebservermergetomega 2018-02-24 16:24:32 +01:00
Bartlomiej Zimon ef1bf646ab Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega 2018-02-24 10:32:09 +01:00
Bartlomiej Zimon f72a48ffc2 - extend conditions with AND/OR, now it is possible to simplify rules
test rules:
on test do
  if [test#a]=0 or [test#b]=0 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test2 do
  if [test#a]=1 and [test#b]=1 and [test#c]=1
    event ok
  else
    event nok
  endif
endon

on test3 do
  if [test#a]=1 and [test#b]=1 or [test#c]=0
    event ok
  else
    event nok
  endif
endon

on test4 do
  if [test#a]=0
    event ok
  else
    event nok
  endif
endon
2018-02-24 10:19:12 +01:00
ESPEasy release bot da54ddda78 automaticly updated release notes for mega-20180224 2018-02-24 04:00:06 +01:00
Bartłomiej ZimońandBartlomiej Zimon 03ee569510 provide System@Sleep event (#875)
- provide System@Sleep event
- fixes #870 (mqtt not sent before sleep)
- call deepsleep at the end of loop - so we know all is done
2018-02-23 19:57:01 +01:00
mvdbro c24205713d ESP32 fixed P020 and P044 2018-02-23 15:21:48 +01:00
s0170071andGitHub 52d4cb804e Merge branch 'mega' into 2kwebservermergetomega 2018-02-23 15:07:18 +01:00
mvdbro ae077de72b Fix ESP32 compile errors 2018-02-23 14:38:14 +01:00
s0170071 86fa5ec6ae Merge into mega
... and removed obsolete function
2018-02-23 14:07:46 +01:00
s0170071 41c9d68422 Merge remote-tracking branch 'origin/mega' into 2kwebservermergetomega 2018-02-23 14:00:19 +01:00
ESPEasy release bot e713da5d79 automaticly updated release notes for mega-20180223 2018-02-23 04:00:07 +01:00
GHolliandDatuX edc261ca2b * BugFix: According to the data sheet, the offset for the detection range values (command byte 0x99) is 3..4 instead of 6..7 (#921)
Reference: http://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19b-co2-ver1_0.pdf
* Optimisation of the code
  - Using an enumeration for the commands to send
  - Removing redundancy of the commands stored in flash
  - Creating a function for the checksum calculation
2018-02-22 19:11:35 +01:00
s0170071andDatuX 8f4a52a6f1 Include name of binary file in crc2.py and sysinfo (#918)
* preparations for lwip2

* Add CRC32 to settings

* Add CRC to progmem

* Add crc of program memory to stettings and security settings

.. so that there is a warning if the settings are used by another binary than they were written with.

* Moved to md5

* Flash included, moved to MD5 now

* Broken comment

* Stability improvements

free memory went as low as 3000 bytes which made the webserver unresponsive.

* Add binary filename to crc2.py and sysinfo

* Update WebServer.ino
2018-02-22 18:55:45 +01:00
ESPEasy release bot af519748a6 automaticly updated release notes for v2.0-20180221 2018-02-21 04:00:20 +01:00
ESPEasy release bot c04b80b2f1 automaticly updated release notes for mega-20180221 2018-02-21 04:00:09 +01:00
Edwin Eefting cdbc2498c1 [test suite] corrected PUYA test. added erase/build/flash for all chips. preparations for full automatic hardware regression testing 2018-02-21 02:44:57 +01:00
Edwin Eefting 78997b4329 Merge branch 'v2.0' into mega 2018-02-21 02:11:18 +01:00
Edwin Eefting 2bece45712 apply PUYA patch to all available frameworks 2018-02-21 02:08:06 +01:00
Gijs NoorlanderandDatuX 10c73a001a [issue #899 ] Backport of DHT22 implementation on Mega (#913)
It has quite some changes, but according to [litrinhos](https://github.com/letscontrolit/ESPEasy/issues/899#issuecomment-366940174) it works, instead of the v2.0 implementation.
2018-02-21 01:26:08 +01:00
GHolliandDatuX 790a946cf6 Optimisation: Save RAM (freeing RAM by moving static data from RAM to program memory). (#910) 2018-02-21 00:02:59 +01:00
Stanislav MihicandDatuX 69c5be6489 Frontend (#906)
* Updating template structure, adding viewport meta name for mobile devices, feature ready for responsive layout

* Adding meta viewport, feature ready nad support for mobile devices, responsive layout, update template structure, adding article html5 tag, easier to style interface, find/replace uppercase to lowercase, matter of elegance and preference code readability :-)

* revert to default state and change only template related lines

* final check, revert uppercase

* Last template changes, lost in undo process :-)

* h6 footer TR
2018-02-20 23:54:46 +01:00
ESPEasy release bot 233ca2bf43 automaticly updated release notes for v2.0-20180220 2018-02-20 04:00:19 +01:00
ESPEasy release bot 3de400fc91 automaticly updated release notes for mega-20180220 2018-02-20 04:00:08 +01:00
Edwin Eefting edeea02f71 SENSOR_TYPE_TEMP_BARO changed, was probably implemented incorrectly before 2018-02-20 01:56:40 +01:00
Edwin Eefting 6fae1f79d8 function was moved to StringConverter.inp 2018-02-20 01:20:57 +01:00
Edwin Eefting 1222e04caf Merge branch 'v2.0' into mega 2018-02-20 01:08:29 +01:00
Bartłomiej ZimońandDatuX f38973aad6 - pcfgpio,port,2 sets pin as input (#897)
- fix for #222,#702 - we can mix inputs and outputs now
2018-02-20 00:57:55 +01:00
Gijs NoorlanderandDatuX b31b1d913f [issue #893] Fix globalSync not working when no controllers active (#896)
* [issue #893] Fix globalSync not working when no controllers active

See #893 and [this topic on the forum](https://www.letscontrolit.com/forum/viewtopic.php?p=24851#p24851)

* [issue #893] Global Sync call when no other controllers active
2018-02-20 00:52:43 +01:00
Gijs NoorlanderandDatuX fa3d4af8cb [Cleanup] Move String manipulating functions to single file (#895)
Makes it easier to re-use functions and improve them.
2018-02-20 00:52:18 +01:00
Gijs NoorlanderandDatuX 29320aab90 [isue #877] Add VCC enable firmware file to release list (#894)
* [isue #877] Add VCC enable firmware file to release list

Added one for the testing build.
Not sure if we should add one for every build, since these flags will lead to an explosion of release versions. 
But at least we will test builds with FEATURE_ADC_VCC define enabled more often.

* Add define FEATURE_ADC_VCC to the PUYA build

Since it is so hard to make a puya version on your own.
2018-02-20 00:50:56 +01:00
Gijs NoorlanderandGitHub 3bc8609611 Merge pull request #905 from TD-er/bugfix/DHTinit_sequence_wrong
[issue #899] DHT22 readings not received
2018-02-20 00:16:51 +01:00
Gijs NoorlanderandGitHub c43d6b3769 Merge pull request #904 from TD-er/feature/log_event_name
[Event Log] Add event name to event processing time log
2018-02-20 00:16:19 +01:00
Gijs NoorlanderandGitHub e9e2ea32ed Merge pull request #903 from TD-er/bugfix/OpenHAB_MQTT_topic_parser_fix
[issue #847] Fix last letter of command is cut in OpenHAB MQTT
2018-02-20 00:15:51 +01:00
Unknown 24b7d1f438 [issue #899] DHT22 readings not received
Applied fix as suggested here: https://github.com/adafruit/DHT-sensor-library/issues/48
2018-02-20 00:04:13 +01:00
Unknown 4febf08501 [Event Log] Add event name to event processing time log
As suggested on the forum by [Methusalem](https://www.letscontrolit.com/forum/viewtopic.php?p=24887#p24887)
2018-02-19 23:31:19 +01:00
Unknown 7f4eae19f4 [issue #847] Fix last letter of command is cut in OpenHAB MQTT
Thanks [jivkopavlovski](https://github.com/letscontrolit/ESPEasy/commit/f23d9fa3d3def506e1401c2208c8a19a1d5d1da2#commitcomment-27660279) for pointing this out (and testing ofcourse)
2018-02-19 22:57:57 +01:00
ESPEasy release bot c13952d04c automaticly updated release notes for v2.0-20180219 2018-02-19 04:00:19 +01:00
ESPEasy release bot 3032463917 automaticly updated release notes for mega-20180219 2018-02-19 04:00:09 +01:00
Bartlomiej Zimon f5e84a155e - pcfgpio,port,2 sets pin as input
- fix for #222,#702 - we can mix inputs and outputs now
2018-02-19 01:38:52 +01:00
Edwin Eefting bbb97bfc7e Merge branch 'v2.0' into mega 2018-02-18 19:23:09 +01:00
Gijs NoorlanderandDatuX e51f7683a5 [issue #890] Split overlap for both Domoticz controllers to helper (#891)
* [issue #890] Split overlap for both Domoticz controllers to helper

Both Domoticz controllers had quite some overlap in code.
And where they differ, one of them was faulty and/or already fixed.

Now this overlap is split into a Domoticz helper file to keep code duplication to a minimum.

* [issue #890] Fix some wierd data corruption

Do not store references in a Json object, but just the string :)

* [Domoticz] Add WiFi strength and battery info
2018-02-18 13:18:23 +01:00
Gijs NoorlanderandDatuX e747756dd2 [Build Mega] Fix for Build Mega 20180217 (#889) 2018-02-18 13:17:02 +01:00
Gijs NoorlanderandDatuX 1ad6fd6ea0 [issue #885] MAC address as system variable (#887)
%mac% will be replaced by the MAC-address of the ESP board.
%mac_int% will show the integer representation of the last 24 bits (MAC address without the OUI part) for use in rules.
2018-02-18 13:16:42 +01:00
ESPEasy release bot d2ec15a4bf automaticly updated release notes for v2.0-20180218 2018-02-18 04:00:11 +01:00
Gijs NoorlanderandDatuX f23d9fa3d3 [issue #847 ] OpenHAB MQTT rewrite topic parser (#886)
* [issue #847 ] OpenHAB MQTT rewrite topic parser

When OpenHAB MQTT controller was selected, the web interface becomes unresponsive when the controller tab was selected.
Also the ESP almost freezes when MQTT messages were sent.

This is an attempt to make them work faster.
Also a lot of string manipulation, copies and resizes are now no longer needed and the received values are checked to be valid int or float before used.

* signed unsigned warning
2018-02-17 13:18:52 +01:00
s0170071 6df5840db9 Fixed String redeclaration 2018-02-17 09:45:40 +01:00
s0170071 5f79e4b922 Merge Webserver 2018-02-17 09:43:46 +01:00
s0170071 e058507b9a Merge remote-tracking branch 'origin/mega' into 2kRamWebserver 2018-02-17 09:26:32 +01:00
ESPEasy release bot 3cea522ec4 automaticly updated release notes for v2.0-20180217 2018-02-17 04:00:18 +01:00
ESPEasy release bot 5c4defdf6e automaticly updated release notes for mega-20180217 2018-02-17 04:00:07 +01:00
Edwin Eefting e58ea2a3fe Merge branch 'v2.0' into mega 2018-02-16 21:43:23 +01:00
Gijs NoorlanderandDatuX a93a078c0b [issue #869] Added 'LWT' to last will topic and improved CPU load (#883)
* [issue #869] Added 'LWT' to last will topic and improved CPU load

See #869 for discussion on Last Will Topic.
Also changed the way it tried to reconnect to make it return a lot faster when connection is not (yet) possible and call the PubSubClient::loop() at a much slower pace to reduce CPU usage. (See #847)
This higher CPU load was probably introduced when fixing #683.

* [MQTT] Fix error reporting success status with longer payloads

Applied PR https://github.com/knolleary/pubsubclient/pull/360/files

* made MQTT_CALLBACK_SIGNATURE for esp32 functional

Applied PR https://github.com/knolleary/pubsubclient/pull/336
2018-02-16 21:32:53 +01:00
Gijs NoorlanderandDatuX 0e0e7be95a [OLED Framed] ESP Easy logo (#876) 2018-02-16 21:29:44 +01:00
Bartłomiej ZimońandDatuX 2b7a61469f provide System@Sleep event (#875)
- provide System@Sleep event
- fixes #870 (mqtt not sent before sleep)
- call deepsleep at the end of loop - so we know all is done
2018-02-16 21:28:52 +01:00
Gijs NoorlanderandDatuX ce02c9e039 [issue #853] Favicon.ico (#874)
* [issue #853] Favicon.ico

Added a very small favicon.ico of the ESPeasy logo. (1150 Bytes, 16x16)

* [Favicon] Added instructions to change icon.

In the comments. Just use 'xxd' from the (Linux) commandline.
2018-02-16 21:27:58 +01:00
Gijs NoorlanderandDatuX 1e9dc1d14c [issue 866] Try to stop logging to serial when serial is not read. (#868)
First attempt, not clear yet how to detect it.
See #866

Also preparation for future improvement on logging. (to detect whether there is some logging active so Strings may not have to be prepared.
2018-02-16 21:26:18 +01:00
s0170071andGitHub 75f1c6c140 Update .gitignore 2018-02-14 20:56:44 +01:00
ESPEasy release bot 9a6f7360da automaticly updated release notes for v2.0-20180214 2018-02-14 04:00:21 +01:00
ESPEasy release bot e3cd057ad8 automaticly updated release notes for mega-20180214 2018-02-14 04:00:10 +01:00
Edwin Eefting fec069ba00 Merge branch 'v2.0' into mega 2018-02-14 03:27:15 +01:00
Edwin Eefting d835ef679c updated deploy script for PUYA 2018-02-14 03:23:50 +01:00
Edwin Eefting 9144e7901b travis build fix for PUYA 2018-02-14 03:10:30 +01:00
Edwin Eefting 858ce397c3 workaround for PUYA flash chips with write issues #650 2018-02-14 03:01:42 +01:00
Gijs NoorlanderandDatuX 78c9ff70be [v2.0] Blynk controller (#865)
* update Blynk controller

- use of real controller index
- we use idx
- check if password not empty
- use real password

* fix for Blynk Controller

- use of real controller index
- we use idx
- check if password not empty
- use real password
- use proper port

* Update _C012.ino

add SENSOR_TYPE_SWITCH support

* [v2.0] Blynk controller
2018-02-14 00:23:59 +01:00
Bartłomiej ZimońandDatuX b2db97e808 fix for Blynk Controller (#863)
* fix for Blynk Controller

- use of real controller index
- we use idx
- check if password not empty
- use real password
- use proper port

* Update _C012.ino

add SENSOR_TYPE_SWITCH support
2018-02-14 00:23:38 +01:00
s0170071 4e537461f2 Fix travis
unsigned int -> int comparison
2018-02-13 21:59:18 +01:00
s0170071 dc7bb12581 4->12 Devices per page
that was easy :-)
2018-02-13 21:53:04 +01:00
s0170071andGitHub 0c80cdc119 Merge branch 'mega' into 2kRamWebserver 2018-02-13 21:36:05 +01:00
s0170071 37210031b7 Cleanup and +1k Ram
- on 2.4.0 git /low mem LWIP ram goes never below 20k, during TX core dives down to 18,7k (each main menu clicked once, plain new config.)
- Fixed json output
- cleanup of send function#
- un-split css, transfer to buffer byte by byte (prevents 1.7k temporary string)
- removed commented-out function
2018-02-13 21:28:10 +01:00
ESPEasy release bot 40eb3e7ceb automaticly updated release notes for v2.0-20180213 2018-02-13 04:00:20 +01:00
ESPEasy release bot d7134e6b87 automaticly updated release notes for mega-20180213 2018-02-13 04:00:09 +01:00
Edwin Eefting 8dc1924059 Merge branch 'v2.0' into mega 2018-02-13 03:16:06 +01:00
Edwin Eefting a7b77b6008 make blynk stuff compile again 2018-02-13 03:11:09 +01:00
Gijs NoorlanderandDatuX 88320d25fc [MQTT] Allow for background tests while waiting for wifi (#860)
Recent changes in 'early exit' when not connected, triggered lots of retry events.
Added some function to allow to wait for WiFi and in the meantime do some background tasks.
2018-02-13 03:01:15 +01:00
Edwin Eefting 649305a2dd Merge branch 'v2.0' into mega 2018-02-13 01:43:11 +01:00
Gijs NoorlanderandDatuX d49197a621 [issue #825] Change labels and password form for Thingspeak controller (#849)
See #825

Added option for controllers to change their display string on some controller fields in the web interface.
When password field label is non-default it also implies to use a visible textfield instead of a password field.
2018-02-13 01:17:04 +01:00
Henri de JongandDatuX 2371b0f315 Added support for pioneer ir signals (#844) 2018-02-13 01:14:44 +01:00
Gijs NoorlanderandDatuX 9abdd097c9 Formatting user vars (re-do of PR#482) + enabled check OpenHabMQTT (#851)
Re-implementation of PR #482 which was done on Mega branch.
Just to keep merges simple between branches. (and improve readabilit)

Also added a simple check to C005 (OpenHAB MQTT) on receiving messages. (see #847 )
2018-02-13 01:07:24 +01:00
Gijs NoorlanderandDatuX f8849cb601 Bugfix/oled framed less memory (#859)
* [OLED] Move font to oled lib dir

It is specific for use wth that library.

* [OLED framed] Stop reading from flash constantly and live update WiFi

See #857
The OLED Framed plugin was reading from spiffs all of the time (on every display update)
Now the data is only read from SPIFFS when needed.
Also made the WiFi strength indicator update every second (only when changed) to be able to see changes in WiFi status much easier.
2018-02-13 01:05:36 +01:00
soifandDatuX b293e8fee0 P012 - Fix/handle lines exceeding LCD width + allow to clear line b4 print (#852)
* Update Library LiquidCrystal_I2C to the latest version

* Fix LCD command (when message is longer than columns) that get split into the wrong lines - issue #603

* Added a "LCD command mode" parameter to handle how exceeding message would be treated, and if the line should be first padded with space.
2018-02-13 01:03:24 +01:00
Gijs NoorlanderandDatuX 11b1c8505a [v2.0] Fix compile errors on ESP32 (#848)
Cherry pick from Mega branch to avoid future merge conflicts.
2018-02-13 00:39:12 +01:00
Gijs NoorlanderandDatuX 9cb3ceed83 [P001 Switch] Fix a mixup in previous fix for switch (#845)
It was causing issues when people upgraded from previous builds.
Leaving it would cause high CPU loads, instable wifi, and incorrect set switch type when upgrading from older builds.

Only thing is when people were using it as a dimmer and used one of the builds in the last few weeks.
Then it will be used as a 'switch', not a dimmer. Change and set and all is fine again.
2018-02-13 00:38:51 +01:00
Gijs NoorlanderandDatuX 2ac1df9482 [issue #839] Add command support for setting contrast for OLED Framed (#841)
* [issue #839] Add command support for setting contrast for OLED Framed

See #839

* [issue #839] Should not use 0 as off value, since that is default

With 0 as "off", the display would be off when not set.
Changed it to 1, which is not a value that can be set other than with the commands
2018-02-13 00:38:01 +01:00
Gijs NoorlanderandDatuX 59b7768722 Blynk controler (re-implementation of PR#92) (#837)
* Blynk controler (re-implementation of PR#92)

See #92
This plugin is just ported from the old implementation, which was not merged into the Mega branch.
It now is using a lot of the newly created functions and optimizations.
But not yet tested.

* Update _C012.ino
2018-02-13 00:32:02 +01:00
Gijs NoorlanderandDatuX d4e5742b1c [#804] Degree symbol for non-framed OLED display (#835) 2018-02-13 00:24:32 +01:00
s0170071 baa1df620f Travis... 2018-02-12 16:55:24 +01:00
s0170071 a310811919 fix Travis
uninitialized variable.
2018-02-12 13:46:36 +01:00
s0170071 e9dd5da690 Add Ram usage debug message
usually shows: 
Ram usage: Webserver only: 1048 including Core: 3120
2018-02-12 11:48:01 +01:00
s0170071 f9c25489d1 fix download page
don't stream this one.
2018-02-12 09:26:00 +01:00
s0170071 46ee928b07 navMenuIndex
fixed order. Needs to be set before stream starts.
2018-02-12 08:11:15 +01:00
s0170071 3af102f2ad Unused variable 2018-02-12 07:07:12 +01:00
s0170071 ca53ec0263 fix travis
unused variable
2018-02-12 06:48:46 +01:00
s0170071 5ca7c073f1 fix travis 2018-02-12 06:34:19 +01:00
ESPEasy release bot f815564dc7 automaticly updated release notes for v2.0-20180212 2018-02-12 04:00:22 +01:00
ESPEasy release bot b320c2a1e2 automaticly updated release notes for mega-20180212 2018-02-12 04:00:09 +01:00
Gijs NoorlanderandDatuX 2b51a4d7c4 [Issue #831] Use DOUT flash mode (#834)
Set DOUT flash mode in the firmware image.
2018-02-12 02:24:16 +01:00
soifandDatuX 01d0723424 Add Device Name in /json page (#815)
* Add Name in /json page

* Json dev friendly (updatable) syntax

* Reorder Json field
2018-02-12 02:11:01 +01:00
s0170071 3f68154819 Merge branch 'webserverminmem' into mega 2018-02-11 22:24:17 +01:00
s0170071 7b1c4483bb Merge remote-tracking branch 's0170071/webserverminmem' into webserverminmem 2018-02-11 22:23:50 +01:00
s0170071 572d9c0714 2k Webserver 2018-02-11 22:23:38 +01:00
mvdbro b85010006b Fix compile errors on ESP32 2018-02-11 14:46:08 +01:00
s0170071 48643cf87e Merge remote-tracking branch 's0170071/webserverminmem' into webserverminmem 2018-02-09 12:28:17 +01:00
s0170071 9ea594afeb Optimized memory usage
memory never goes below 10k now. 
Added wait for memory return on header send, 
Added wait for memory return on chunk end send,
removed duplicate of data stashing with  getWebPageTemplateVar
2018-02-09 12:27:45 +01:00
ESPEasy release bot aec539be43 automaticly updated release notes for v2.0-20180209 2018-02-09 04:00:26 +01:00
ESPEasy release bot 749c8cd931 automaticly updated release notes for mega-20180209 2018-02-09 04:00:15 +01:00
s0170071 49a783c381 "Content-Type","text/html" 2018-02-08 20:11:07 +01:00
s0170071 c9b81f7ab9 Wait for memory be like before send chunked
goes not below 9680 bytes now
2018-02-08 19:57:16 +01:00
AndreyandDatuX eb2dbb5b90 Added HIGH-Z state options for GPIO command (#833)
Add command like 'GPIO,12,2' for set pin to HIGH-Z (INPUT) state.
2018-02-08 19:37:52 +01:00
wdonkerandDatuX e49f31121c Add trigger for rulesprocessing (#826)
* Update _C002.ino

Trigger rulesprocessing om MQTT receive message

* Replace direct call by createRuleEvents

Change to createRuleEvents
2018-02-08 19:33:32 +01:00
s0170071 91c6e3af61 Does Travis like extern "C" ? 2018-02-08 17:31:26 +01:00
s0170071 faeb921bcf Merge remote-tracking branch 's0170071/webserverminmem' into webserverminmem 2018-02-08 17:13:01 +01:00
s0170071 9928f56ad3 try fix travis 2018-02-08 17:12:53 +01:00
s0170071andGitHub 61d27084c1 trigger travis re-compile
trigger travis re-compile to see if the compile failure was due to a quick re-submission.
2018-02-08 10:04:07 +01:00
s0170071 e5393a9fa4 Adapted timeout 2018-02-07 22:08:43 +01:00
s0170071 1cbc49021a tcp_cleanup for LWIP1 & 2 2018-02-07 22:04:39 +01:00
s0170071 84f389b44e Timeout 100ms 2018-02-07 17:29:16 +01:00
s0170071 765775e22f Adjusted to min 7k free 2018-02-07 17:21:28 +01:00
s0170071 02c97c4513 Webserver min memory
memory went as low as 3k, so wait for it to return ...
2018-02-07 17:15:23 +01:00
ESPEasy release bot bd874c4a13 automaticly updated release notes for v2.0-20180206 2018-02-06 05:00:21 +01:00
ESPEasy release bot d87cd7eafe automaticly updated release notes for mega-20180206 2018-02-06 05:00:10 +01:00
Edwin Eefting 58bb62cc1a Merge branch 'v2.0' into mega 2018-02-06 01:08:36 +01:00
Gijs NoorlanderandDatuX 6b8ea6c15b [issue #727] Proper user interface to set DST rules (#823)
See #727
And it only took 4 bytes extra storage :)

When initialized with an invalid setting for DST, (like fresh after flashing), it will use the CEST/CET setting.
2018-02-06 00:42:45 +01:00
Gijs NoorlanderandDatuX a62dd5ce8f [issue #817] Added mail header to SMTP (#820)
* [issue #817] Added mail header to SMTP

N.B. use only mail address (no name, no '<>' etc) as sender.

* [SMTP] Add user/pass to send email.

* [issue #817] Added user + passwd authentication to SMTP notifications

Tested with smtp2go.com (non TLS mail proxy)
It is now possible to add username + passwd when sending mail.
If both left empty, authentication will not be used.
2018-02-05 23:59:24 +01:00
Gijs NoorlanderandDatuX 92889b6cf1 Backport OLED framed from mega + support special characters (#818)
* [OLED framed] Backport of OLED lib upgrade from Mega to v2.0

Lots of issues with older lib and the newer version in the Mega branch appeared to be very stable.

* [OLED framed] Use less string allocations

And a first attempt to display the Euro sign. (does not yet work)

* [Special Char] Allow to use special characters

For some special characters, it is often hard to find them and/or use them in URL or JSON streams.
For a subset of supported special characters, a short notation and HTML equivalent is added.
These can be used anywhere.

* [OLED lib] Fixed memory leak

Man library did some allocs without free.
Also unneeded allocs.

* Applied pull requests from esp8266-oled-ssd1306:
https://github.com/squix78/esp8266-oled-ssd1306/pull/169
https://github.com/squix78/esp8266-oled-ssd1306/pull/157
https://github.com/squix78/esp8266-oled-ssd1306/pull/144

And applied the suggestions from issues:
https://github.com/squix78/esp8266-oled-ssd1306/issues/170
https://github.com/squix78/esp8266-oled-ssd1306/issues/161

* [OLED] Support multiple display resolutions

Applied PR from esp8266-oled-ssd1306:
https://github.com/squix78/esp8266-oled-ssd1306/pull/133

* [OLED] Better Brightness / Contrast control

Suggestions taken from this issue:
https://github.com/squix78/esp8266-oled-ssd1306/issues/134

* [OLED] Set contrast to High by default, when no choice was made

Sounds like a valid choice, based on the findings in issue #821

* Compiler error on comments

As suggested here: https://github.com/TD-er/ESPEasy/pull/3/files
2018-02-05 23:56:17 +01:00
soifandDatuX b5479575eb All Advanced Settings as 'DEFAULT_' Defines (#813)
* Implements all Advanced Settings as "DEFAULT_" defines

* Organise and comment "DEFAULT_" defines
2018-02-05 23:50:48 +01:00
s0170071andDatuX 201d013230 Add compile time (#811) 2018-02-05 23:49:26 +01:00
ESPEasy release bot 6fead68f34 automaticly updated release notes for v2.0-20180203 2018-02-03 05:00:20 +01:00
ESPEasy release bot 9a77b1727c automaticly updated release notes for mega-20180203 2018-02-03 05:00:11 +01:00
GrovkillenandGitHub 2f26cd13bc Update README.md 2018-02-02 12:52:12 +01:00
GrovkillenandGitHub f0d35527df Update README.md
Made the "warning" stand out a bit more.
2018-02-02 12:50:58 +01:00
ESPEasy release bot 3a9ef290e8 automaticly updated release notes for v2.0-20180202 2018-02-02 05:00:23 +01:00
ESPEasy release bot 9cbaa4d7e7 automaticly updated release notes for mega-20180202 2018-02-02 05:00:12 +01:00
Edwin Eefting af4ad9fbcb Merge branch 'v2.0' into mega 2018-02-02 03:17:01 +01:00
soifandDatuX 36a9bdae72 Json page also Shows Git Build (#808)
* remove un-needed spaces in JSON (save some memory?)

* Add the Git Build string in the /json page
2018-02-02 03:11:02 +01:00
soifandDatuX ebfa0a45a6 Custom define file (#807)
* Allows to use a Custom.h file to change defaults setting without changing the repo file

* Custom.h example
2018-02-02 02:40:56 +01:00
soifandDatuX c2e70360c4 Allows to define the IP address when in AP Mode (#806) 2018-02-02 02:39:47 +01:00
Edwin Eefting 8bdfa656de Add CRC checks to all binaries when building a release with travis. fixes #779 2018-02-02 02:27:23 +01:00
Edwin Eefting 952bf68b93 Merge branch 'v2.0' into mega 2018-02-02 01:37:35 +01:00
DatuXandGitHub 712a5e80d0 Update README.md 2018-02-02 01:23:42 +01:00
DatuXandGitHub a44069ae26 Update README.md 2018-02-02 01:17:06 +01:00
DatuXandGitHub 13f73c0156 Update README.md 2018-02-02 01:15:34 +01:00
soifandDatuX bb88225cab Fix Syslog : include Hosname instead of Unit Number - now RFC3164 compliant (#805) 2018-02-02 00:40:04 +01:00
Gijs NoorlanderandDatuX 3089b288b2 [issue #739] Reconnect MQTT when Unit Name has changed. (#803)
See #739
When %sysname% has changed, force a reconnect of the MQTT client.

Also made the client ID guaranteed unique by using the MAC address.
2018-02-02 00:38:28 +01:00
soifandDatuX 6abea46eb5 Fixes invalid '/json' page output format : DateTimeString is now correctly quoted (#802) 2018-02-02 00:37:01 +01:00
Gijs NoorlanderandDatuX ffa73aee59 [v2.0] Resource friendly string replacement (#798)
As part of #698 and also since these system variable replacement may grow.
Some replacement strings may need some work to create and such effort is wasted if the matching string does not occur.
To improve this and still remain readable, I added a simple macro to check first and then create the strings only when needed.
Some strings are already present, so these do not use the macro since searching first and then look again to replace will take more effort.
2018-02-02 00:34:02 +01:00
Gijs NoorlanderandDatuX f4b7e97997 [issue #794] Add longpulse_ms command (#796)
See #794
2018-02-02 00:30:49 +01:00
Gijs NoorlanderandDatuX b32212b061 [Mega] Fix pointer arithmetic on void pointers for CRC computations (#795)
It was a change I made last week to get it to compile for the 2.4.0 core lib, but made an error in the pointer arithmetic.
No it shoud be correct.
See https://github.com/letscontrolit/ESPEasy/issues/792#issuecomment-361714575
2018-02-02 00:28:58 +01:00
ESPEasy release bot 66d0de684a automaticly updated release notes for v2.0-20180130 2018-01-30 05:00:23 +01:00
ESPEasy release bot cae3baf71e automaticly updated release notes for mega-20180130 2018-01-30 05:00:12 +01:00
Edwin Eefting 27db33f1bd Merge branch 'v2.0' into mega 2018-01-30 01:54:10 +01:00
Gijs NoorlanderandDatuX 23d5709957 [Log] Clean up of log routines and more intuitive log level input (#788)
As part of #781, #747 and the general cleanup issue #698.
2018-01-30 01:50:24 +01:00
Edwin Eefting b96e12f217 Merge branch 'v2.0' into mega 2018-01-29 22:52:14 +01:00
Gijs NoorlanderandDatuX 16eb08afa0 [#784] Add %rssi% as system variable (#786)
* [#784] Add %rssi% as system variable

See #784

* [#787] Add %unit% and %ssid% system variable

See #787
Unit is the unit number of the ESP device.
SSID is the name of the WiFi accesspoint the ESP device is connected with.
2018-01-29 22:51:26 +01:00
Edwin Eefting ad8e229c06 Merge branch 'v2.0' into mega 2018-01-29 20:52:56 +01:00
Gijs NoorlanderandDatuX b9b7ceccb6 Bugfix/issue 740 allow mqtt as controller 2 3 (#785)
* [issue #740] Allow MQTT controller to be on any controller

See #740

Still there is an issue when >1 MQTT controller is selected and enabled.
Currently only one MQTT controller may be active.

* [issue #740] Add warning when >1 MQTT controller is active

Add a warning to the web interface when >1 MQTT controller is active.
See #740
2018-01-29 18:12:47 +01:00
Edwin Eefting 5c4bf52b66 forgot to commit last framed oled display fix 2018-01-29 17:30:01 +01:00
ESPEasy release bot 34369d268e automaticly updated release notes for v2.0-20180126 2018-01-26 05:00:22 +01:00
ESPEasy release bot 0ec7085022 automaticly updated release notes for mega-20180126 2018-01-26 05:00:12 +01:00
Edwin Eefting 913cd67eee Merge branch 'v2.0' into mega 2018-01-25 22:15:57 +01:00
Gijs NoorlanderandDatuX 3292051bae Update _C007.ino (#774) (#776)
This change allows to send the switch state to Emoncms, previously it was ignored
2018-01-25 22:07:07 +01:00
Gijs NoorlanderandDatuX 2586b94e28 [Mega] Force 2.3.0 for all builds and add an option for 2.4.0 core (#775)
* [Mega] Force 2.3.0 for all builds and add an option for 2.4.0 core

This way we can test issues easier and people are still using 2.3.0 core version.

* Update platformio.ini

Environment labels should not use dots. Then they will not show in the build selection box.
2018-01-25 22:06:45 +01:00
Gijs NoorlanderandDatuX d492347f31 [V2.0] Allow IRremoteESP8266 to be built with core 2.4.0 (#773)
* [V2.0] Allow IRremoteESP8266 to be build with core 2.4.0

A partial cherrypick of #772, to make merging easier.
Just some simple patches on the use of min() and max() in the library to allow it to compile using the 2.4.0 core lib. Actual use of this core lib is still prohibited by the check in ESPEasy.ino.

* [core 2.3.0] Force PlatformIO to use the 2.3.0 core libs

This update forces the PlatformIO environment to load the 1.5.0 version of espressif8266@1.5.0, which uses Core 2.3.0
2018-01-25 22:04:54 +01:00
josemariaaraujoandDatuX b811b13483 Update _C007.ino (#774)
This change allows to send the switch state to Emoncms, previously it was ignored
2018-01-25 15:49:31 +01:00
Gijs NoorlanderandDatuX 56f9bc9c3a [issue #759] Disable Senseair ABC due to firmware issues (#771)
See #759

Just commented the Set ABC functionality. People may compile it for themselves, but be aware of possible consequences.
2018-01-25 15:48:21 +01:00
Gijs NoorlanderandDatuX c149888bed [Mega] Allow compile with 2.4.0 core library (#772)
Last few days, lots of issues reported by users who installed the 2.4.0 core libraries.
e.g. #769 and #763
It appeared the default PlatformIO Espressif 8266 1.6.0 libs now include the 2.4.0 core libraries.
Now I have to find a way to get my own environment back to the 2.3.0 core libs and see how I can get PlatformIO Espressif 8266 library back to version 1.5.0
2018-01-25 15:47:58 +01:00
ESPEasy release bot 82cea3db2e automaticly updated release notes for v2.0-20180124 2018-01-24 05:00:20 +01:00
ESPEasy release bot 8aea298854 automaticly updated release notes for mega-20180124 2018-01-24 05:00:09 +01:00
Edwin Eefting 5617fbe0a0 Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega 2018-01-24 03:17:32 +01:00
Edwin Eefting 6a643da8ee Merge branch 'v2.0' into mega 2018-01-24 03:17:20 +01:00
Edwin Eefting 2f32799b67 fix #718. also update display on save and removed graphical boot logo to conserve space. also fixes #713. (web interface will be non repsonsive during scrolling now, but there is no easy fix for that) 2018-01-24 02:58:25 +01:00
s0170071andDatuX ee568a76c1 Space (#767)
* preparations for lwip2

* Add CRC32 to settings

* Add CRC to progmem

* Add crc of program memory to stettings and security settings

.. so that there is a warning if the settings are used by another binary than they were written with.

* Moved to md5

* Flash included, moved to MD5 now

* Broken comment
2018-01-23 23:55:55 +01:00
s0170071andDatuX beaf077b06 Broken comment (#766)
* preparations for lwip2

* Add CRC32 to settings

* Add CRC to progmem

* Add crc of program memory to stettings and security settings

.. so that there is a warning if the settings are used by another binary than they were written with.

* Moved to md5

* Flash included, moved to MD5 now

* Broken comment
2018-01-23 23:55:29 +01:00
Gijs NoorlanderandDatuX fd5da94f9c [issue #758] P029 MQTT helper does not log anymore (#764)
See #758
2018-01-23 23:54:34 +01:00
ESPEasy release bot 0694fcc5fb automaticly updated release notes for v2.0-20180123 2018-01-23 05:00:20 +01:00
ESPEasy release bot e36a9f163e automaticly updated release notes for mega-20180123 2018-01-23 05:00:10 +01:00
Edwin Eefting 17f0f6637a Merge branch 'v2.0' into mega 2018-01-23 04:58:52 +01:00
Edwin Eefting bc91939757 request mainpage when checking if reboot is complete 2018-01-23 04:57:20 +01:00
Edwin Eefting eb743f95cf added easy reboot warning and function to work around several issues 2018-01-23 04:49:16 +01:00
Edwin Eefting 0ec770fc51 Merge branch 'v2.0' into mega 2018-01-23 02:43:07 +01:00
Edwin Eefting ed4cdc3d90 clear custom task and controller settings when selecting a different device or protocol. replaces #762 . fixes #721 2018-01-23 02:37:02 +01:00
Edwin Eefting 9da5f465d1 Merge branch 'v2.0' into mega 2018-01-23 01:02:12 +01:00
Edwin Eefting 8e72ace3b5 test suite: espcli can now do stuff for all configured nodes 2018-01-23 00:50:00 +01:00
s0170071andDatuX 5230a4fe4f CRC on settings and security settings and progmem (#720)
* preparations for lwip2

* Add CRC32 to settings

* Add CRC to progmem

* Add crc of program memory to stettings and security settings

.. so that there is a warning if the settings are used by another binary than they were written with.

* Moved to md5

* Flash included, moved to MD5 now
2018-01-22 23:58:43 +01:00
Edwin Eefting b236887718 Merge branch 'v2.0' into mega 2018-01-22 23:54:55 +01:00
Gijs NoorlanderandDatuX 2527cbe097 Central function for system variable replacement (#757)
* Central function for system variable replacement

Related to:
- #698 => Not complete
- #709 => fixed
- #751 => fixed

Redesign of PR #485 (in mega branch)

One note: no sensor values can be used in controllers. Is this what we want, or should we call parseTemplate everywhere parseSystemVariables is being used?
Also not all controllers apparently allow system variables. Is this also correct?

* [issue 757] Add %lcltime% to display date + time

As requested by @PsychoAndi at PR #757

* [issue 757] Add local time to JSON output

As suggested by @PsychoAndi
2018-01-22 23:38:14 +01:00
Edwin Eefting cbca4c3efa Merge branch 'v2.0' into mega 2018-01-22 23:35:45 +01:00
Edwin Eefting 5b0e9d934c test suite: now possible to run all tests at once. fixes 2018-01-22 23:32:46 +01:00
ESPEasy release bot 19429e8507 automaticly updated release notes for v2.0-20180122 2018-01-22 05:00:19 +01:00
ESPEasy release bot a67f92176f automaticly updated release notes for mega-20180122 2018-01-22 05:00:08 +01:00
Edwin Eefting 3922827fad Merged v2.0 changes and fixed some regressions 2018-01-22 01:43:42 +01:00
Gijs NoorlanderandDatuX 0c637da19f [#732] Only process P029 MQTT helper when enabled (#743)
See #732
Also did some small optimizations for when no Domoticz MQTT controller enabled and/or task enabled.
2018-01-21 17:10:08 +01:00
Gijs NoorlanderandDatuX 48f168da9d [issue #745] Set IPaddress to 0.0.0.0 when read from empty string (#754)
Also str2ip now uses IPAddress.fromString()
2018-01-21 17:08:15 +01:00
ESPEasy release bot 3357eb287c automaticly updated release notes for v2.0-20180121 2018-01-21 05:00:13 +01:00
Edwin Eefting 5da1c54b70 test suite: fixes. testing boot gpio states 2018-01-21 04:28:12 +01:00
Edwin Eefting c5bbdb401a test suite: lots of refactoring and fixing 2018-01-21 03:23:22 +01:00
Edwin Eefting f69b84d24b test suite: fixed issues, started working on nodo 2018-01-21 01:53:22 +01:00
Edwin Eefting 1250e09fef cleaned up nodo logging. fixed domotics SENSOR_TYPE_WIND inconsistency 2018-01-21 01:52:36 +01:00
Edwin Eefting fbf22ba7af test suite: generelized controller testing in test005 2018-01-20 21:49:24 +01:00
ESPEasy release bot 5c26d50227 automaticly updated release notes for v2.0-20180120 2018-01-20 05:00:12 +01:00
Edwin Eefting 47be037be9 Merge branch 'v2.0' of github.com:letscontrolit/ESPEasy into v2.0 2018-01-19 05:45:10 +01:00
Edwin Eefting bc4f7d390c test suite: started on testcase to test all sensor types via the dummy plugin 2018-01-19 05:44:57 +01:00
Edwin Eefting 9fe64834f9 added QUAD to c002. fixed getBearing and SENSOR_TYPE_WIND. 2018-01-19 05:43:50 +01:00
ESPEasy release bot 4d943c2386 automaticly updated release notes for v2.0-20180119 2018-01-19 05:00:18 +01:00
ESPEasy release bot 4b298d6e31 automaticly updated release notes for mega-20180119 2018-01-19 05:00:07 +01:00
jctualandDatuX c0c65364e5 DHT plugin update (#736)
Modification of DHT plugin to use Sonoff am2301 and si7021 sensors.
Also correct some NAN readings.
2018-01-19 02:43:22 +01:00
Edwin Eefting 51b76682cf test suite: added dht22 2018-01-19 02:35:38 +01:00
Edwin Eefting 5f89698308 Merge branch 'v2.0' into mega 2018-01-19 01:30:40 +01:00
Edwin Eefting 400ee82686 test suite domoticz mqtt + found few fixmes 2018-01-19 01:28:14 +01:00
ESPEasy release bot 485f97bdc2 automaticly updated release notes for v2.0-20180118 2018-01-18 05:00:19 +01:00
ESPEasy release bot 5821377b6c automaticly updated release notes for mega-20180118 2018-01-18 05:00:08 +01:00
Edwin Eefting e6e3c1ddee refactoring test suite controller stuff 2018-01-18 03:37:25 +01:00
Edwin Eefting a6ea35ef9c Merge branch 'v2.0' into mega 2018-01-18 02:15:01 +01:00
Edwin Eefting fe9a579dc3 added fixme 2018-01-18 02:03:54 +01:00
Gijs NoorlanderandDatuX 017aad051e [issue 728] Proper reconnect for MQTT controllers (#737)
See #728
Also looked into the very strange configuration settings lookup for MQTT settings. The way it was, the settings for the first MQTT controller were used even when the actual MQTT controller was inactive or using different settings.

Now the controller selected in the the plugin is being used and when no plugin setting is available (and also for P037 MQTT import) the first active MQTT controller will be used.
2018-01-18 01:04:55 +01:00
Gijs NoorlanderandDatuX 8a30659015 [issue 733] Fix for negative values on MQTT import (#735)
See #733.
The '-' was parsed, but not copied to the tmp char array to be converted.
2018-01-18 00:44:08 +01:00
ESPEasy release bot ed7f597b3d automaticly updated release notes for mega-20180117 2018-01-17 05:00:08 +01:00
Edwin Eefting 6700030d7c Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega 2018-01-17 00:16:09 +01:00
Edwin Eefting f45c7650de fix #719 (initial ds18b20 value after power on 85 degrees) 2018-01-17 00:15:59 +01:00
papperoneandDatuX a36ee65865 merge with main branch (#648)
* removed note for 74HC595

74HC595 pin reminder not needed as this chip won't be supported anymore

* deleted GPIO notes referring to 75HC595 not supported
2018-01-16 20:20:52 +01:00
ESPEasy release bot b61c638f0a automaticly updated release notes for v2.0-20180116 2018-01-16 05:00:21 +01:00
ESPEasy release bot dfb5b8a4c5 automaticly updated release notes for mega-20180116 2018-01-16 05:00:11 +01:00
Edwin Eefting 09e5d6abcd now supports powercycle to test for bugs like #719 2018-01-16 04:15:48 +01:00
Edwin Eefting 2aafbb57a8 made test resumable and importable 2018-01-16 03:41:29 +01:00
Edwin Eefting 9d3dd49e9d Merge branch 'v2.0' into mega 2018-01-16 00:20:12 +01:00
Edwin Eefting 744f22112b Merge branch 'v2.0' of github.com:letscontrolit/ESPEasy into v2.0 2018-01-15 23:04:48 +01:00
Edwin Eefting b38edfb672 fixed custom build path 2018-01-15 23:04:40 +01:00
Gijs NoorlanderandDatuX a73875a2e2 [AutoDST] Added Auto DST (Bugfix/v2.0 issue569) (#726)
* [Time] Moved time related code to separate file

* [AutoDST] Added Auto DST

Preliminary support for Auto DST, as requested in #569
Also did a little refactorin of time related code, with #698 in mind.
All time related code is split into a few files based on its function.

The currently selected DST will start on Last Sunday March 2am and end on Last Sunday October 3am.
This is the most frequently used DST, according to https://en.wikipedia.org/wiki/Daylight_saving_time_by_country

To change it, currently the code has to be changed in the function applyTimeZone(). Several examples are given right below that function.
Problem is where to store the information of the timezone, how to use it in the web interface and how convenient it is to set by hand.
The UTC offset in minutes still has to be entered and whether or not DST should be enabled.
2018-01-15 21:51:15 +01:00
ESPEasy release bot 0833029c82 automaticly updated release notes for mega-20180114 2018-01-14 05:00:08 +01:00
s0170071andDatuX 71cf207bf7 preparations for lwip2 (#707) 2018-01-13 12:22:32 +01:00
ESPEasy release bot f7ea185f80 automaticly updated release notes for v2.0-20180113 2018-01-13 05:00:20 +01:00
ESPEasy release bot 3d3a035822 automaticly updated release notes for mega-20180113 2018-01-13 05:00:10 +01:00
Edwin Eefting 11a94aae25 testsuite: working on generic http/mqtt controller emulatior receiving 2018-01-13 03:21:09 +01:00
Edwin Eefting af3bf5217d fix version number 2018-01-13 03:07:38 +01:00
Edwin Eefting 11f47f26e6 Merge branch 'v2.0' into mega 2018-01-13 03:04:33 +01:00
Edwin Eefting 57c6fbbaab ESPEasy v2.0 only supports compiling under arduino core 2.3.0 to prevent issues like #705 when people use Arduino IDE to compile with arduino core 2.4.0 2018-01-13 02:53:15 +01:00
Edwin Eefting f7b37306aa automaticly updated release notes for mega-20180112 2018-01-12 02:05:49 +01:00
Edwin Eefting 8b3d8f6ad4 Merge branch 'v2.0' into mega 2018-01-12 02:03:58 +01:00
Edwin Eefting 7a9726063d dont make same release twice 2018-01-12 02:02:43 +01:00
Edwin Eefting d6680b604f dont make same release twice 2018-01-12 02:02:27 +01:00
Edwin Eefting 25ef1803e0 release bot fixes 2018-01-12 01:59:03 +01:00
Edwin Eefting 2bc72151bc automaticly updated release notes for v2.0-20180112 2018-01-12 01:56:54 +01:00
Edwin Eefting 93ceae3bef fixed releasebot issues with multiple branches 2018-01-12 01:56:34 +01:00
Edwin Eefting b5cad22afd Merge branch 'v2.0' into mega 2018-01-12 01:41:13 +01:00
Edwin Eefting 2bf31a1985 testsuite requirements 2018-01-12 01:40:20 +01:00
Gijs NoorlanderandDatuX 5796f50439 [v2.0 #470] Do not send invalid values to a controller (#701)
Prevent sending of invalid values (NaN, inf) to any controller.
Simple test is to output any plugin value with formula set to "%value%/0" and try to send it to any controller.
Is a fix for #470 and #693
2018-01-12 01:06:36 +01:00
Edwin Eefting 36415d424e first http domoticz test works 2018-01-12 01:04:47 +01:00
Edwin Eefting 76be5dd8d9 added http server emulation and domotics http to testsuite 2018-01-12 00:50:45 +01:00
Edwin Eefting 407dae03ca merged v2.0 changes 2018-01-11 23:00:15 +01:00
Gijs NoorlanderandDatuX 6e760cd25b [Issue 699] Incorrect shown device name (#700)
And some improvements in readability and performance of webserver.
2018-01-11 22:45:50 +01:00
ESPEasy release bot 69c03cafb9 automaticly updated release notes for v2.0-20180111 2018-01-11 05:00:18 +01:00
ESPEasy release bot c17e683834 automaticly updated release notes for mega-20180111 2018-01-11 05:00:08 +01:00
Edwin Eefting 311abeabd0 Merge branch 'v2.0' into mega 2018-01-11 03:27:25 +01:00
Edwin Eefting b20d4a10ba working on http mocker for test suite 2018-01-11 03:26:30 +01:00
Edwin Eefting 548bf8b867 added frame oled test 2018-01-11 01:49:57 +01:00
Edwin Eefting 0b68e16894 test suite fixes 2018-01-11 01:35:32 +01:00
Edwin Eefting 33e46addbb analysed some code and added comments 2018-01-11 00:54:19 +01:00
Edwin Eefting 04f27e0d03 Merge branch 'v2.0' into mega 2018-01-11 00:52:36 +01:00
Edwin Eefting 628ff925b7 Merge branch 'v2.0' of github.com:letscontrolit/ESPEasy into v2.0 2018-01-11 00:48:44 +01:00
Edwin Eefting 6fddf25a39 copied test-stuff from mega to v2.0 to do some testing 2018-01-11 00:48:24 +01:00
Gijs NoorlanderandDatuX 84e58285af [v2.0_kamstrup] Plugin configuration does not load (#697)
Could not change the device settings. The PLUGIN_WEBFORM_LOAD case was not handled.
2018-01-10 23:22:40 +01:00
Edwin Eefting fc5103de8d oops...somehow git did made some changes :( 2018-01-10 22:34:36 +01:00
Edwin Eefting 14b6345277 no changes, just merge the v2.0 branch 2018-01-10 22:22:29 +01:00
Gijs NoorlanderandDatuX 9a70037e32 Merge/v2.0 dev13 to mega (#695)
* [switch] Fixed switch behavior and default settings. (#675)

As described in #673 .
The problem was partly related to the default values stored in flash ("0"), which was not a valid value for the switch type.

When upgrading from an older version of ESPeasy, make sure to check the switch type (normal switch or dimmer) and save the settings for the switch device again, even when nothing was changed.
Default configuration and new added switches will now work like intended.

When a controller is enabled (e.g. Domoticz MQTT or -HTTP) and the button is pressed multiple times, the ESP may reboot. See issue #674.

* ABC calibration feature added (#606)

* [Flash info] Detailed flash information (#678)

Last few days a number of issues and forum topic was about the type of flash used on the ESP boards.

This is an extension of the detailed information page.

Perhaps also merge with the newer and more clear layout of pull request #624?
That pull request was only merged to the mega branch.
I kept the changes local, but perhaps they should be placed in the "Storage" section introduced with #624.
Maybe also that pull request should get merged into the v2.0 branch.

* Bugfix/v2.0 crash switch (#682)

* [crashes] Added constructors to initialize all members in structs

Numerous structs are defined, but none of them have default constructors and there is no guarantee the members will be set when used. 
With these default constructors, the parameters at least have an initialized value.

* [PubSubClient] Add bound checks on the internal buffer

Not sure if this was really causing an issue, but proper bound checks are always a good thing.

* [Crash Switch] Disabled delayBackground and added yield() calls

Something really fishy is going on with the delayBackground function, which will result in crashes when pressing the switch multiple times, with Domoticz MQTT enabled as first controller.
Disabled for now and delay(1) added to give background tasks a chance to do their work and make sure the watchdog doesn't perform a reset.

* [CI build errors] Commented out some unused variables

Travis considers them as error and fails the checks.

* [CI check] Out-of-bounds check fix

* actually ignore MQTT messages that are too big.

* moved mqtt stuff outside of backgroundtasks(). fixes #683 in my test scenario

* [Adafruit MPR121] Change deprecated name setThreshholds to setThresholds (#685)

See #684

* fixed plugin id of "Communication - Kamstrup Multical 401". (accidental octal notation)

* changed devicecombobox handling to save a lot of memory on device page. fixes #654 #676 and could be triggered by #683 in some cases.

* [CPPcheck] v2.0 ControllerSettingsStruct some variables not initialized (#692)

Fixing these cppcheck errors:
101.43s$ cppcheck --enable=warning src/*.ino -q --force -I src --include=src/ESPEasy.ino --error-exitcode=1
[src/ESPEasy.ino:500]: (warning) Member variable 'ControllerSettingsStruct::HostName' is not initialized in the constructor.
[src/ESPEasy.ino:500]: (warning) Member variable 'ControllerSettingsStruct::Publish' is not initialized in the constructor.
[src/ESPEasy.ino:500]: (warning) Member variable 'ControllerSettingsStruct::Subscribe' is not initialized in the constructor.
2018-01-10 21:51:42 +01:00
Edwin Eefting 3a8323faab Merge branch 'v2.0' of github.com:letscontrolit/ESPEasy into v2.0 2018-01-10 19:19:57 +01:00
Edwin Eefting fe1944922c changed devicecombobox handling to save a lot of memory on device page. fixes #654 #676 and could be triggered by #683 in some cases. 2018-01-10 19:19:48 +01:00
Gijs NoorlanderandDatuX 7ea0c767fa [CPPcheck] v2.0 ControllerSettingsStruct some variables not initialized (#692)
Fixing these cppcheck errors:
101.43s$ cppcheck --enable=warning src/*.ino -q --force -I src --include=src/ESPEasy.ino --error-exitcode=1
[src/ESPEasy.ino:500]: (warning) Member variable 'ControllerSettingsStruct::HostName' is not initialized in the constructor.
[src/ESPEasy.ino:500]: (warning) Member variable 'ControllerSettingsStruct::Publish' is not initialized in the constructor.
[src/ESPEasy.ino:500]: (warning) Member variable 'ControllerSettingsStruct::Subscribe' is not initialized in the constructor.
2018-01-10 19:15:35 +01:00
Edwin Eefting ec18e5c530 updates version numbering documentation 2018-01-10 16:34:58 +01:00
ESPEasy release bot 885781850b automaticly updated release notes for v2.0-20180110 2018-01-10 16:14:23 +01:00
ESPEasy release bot 443b46f383 added releasebot to v2.0 branch 2018-01-10 16:13:24 +01:00
GrovkillenandGitHub 8ce1aa0092 Update README.md
Re-arranged the date format to = the current code standard.
2018-01-10 16:01:27 +01:00
Edwin Eefting 801a591282 fixed plugin id of "Communication - Kamstrup Multical 401". (accidental octal notation) 2018-01-10 15:09:10 +01:00
Gijs NoorlanderandDatuX 740efcb763 [Adafruit MPR121] Change deprecated name setThreshholds to setThresholds (#685)
See #684
2018-01-10 02:45:50 +01:00
Edwin Eefting 67fa39f4ed moved mqtt stuff outside of backgroundtasks(). fixes #683 in my test scenario 2018-01-10 02:25:01 +01:00
Edwin Eefting 7a8bb7c0e0 actually ignore MQTT messages that are too big. 2018-01-10 01:56:05 +01:00
Gijs NoorlanderandDatuX 961b1106aa Bugfix/v2.0 crash switch (#682)
* [crashes] Added constructors to initialize all members in structs

Numerous structs are defined, but none of them have default constructors and there is no guarantee the members will be set when used. 
With these default constructors, the parameters at least have an initialized value.

* [PubSubClient] Add bound checks on the internal buffer

Not sure if this was really causing an issue, but proper bound checks are always a good thing.

* [Crash Switch] Disabled delayBackground and added yield() calls

Something really fishy is going on with the delayBackground function, which will result in crashes when pressing the switch multiple times, with Domoticz MQTT enabled as first controller.
Disabled for now and delay(1) added to give background tasks a chance to do their work and make sure the watchdog doesn't perform a reset.

* [CI build errors] Commented out some unused variables

Travis considers them as error and fails the checks.

* [CI check] Out-of-bounds check fix
2018-01-10 00:49:47 +01:00
Gijs NoorlanderandDatuX 9dc549e62d [Flash info] Detailed flash information (#678)
Last few days a number of issues and forum topic was about the type of flash used on the ESP boards.

This is an extension of the detailed information page.

Perhaps also merge with the newer and more clear layout of pull request #624?
That pull request was only merged to the mega branch.
I kept the changes local, but perhaps they should be placed in the "Storage" section introduced with #624.
Maybe also that pull request should get merged into the v2.0 branch.
2018-01-10 00:35:27 +01:00
chunter1andDatuX c1a11ff6e4 ABC calibration feature added (#606) 2018-01-05 17:11:29 +01:00
Gijs NoorlanderandDatuX 151bf18cc6 [switch] Fixed switch behavior and default settings. (#675)
As described in #673 .
The problem was partly related to the default values stored in flash ("0"), which was not a valid value for the switch type.

When upgrading from an older version of ESPeasy, make sure to check the switch type (normal switch or dimmer) and save the settings for the switch device again, even when nothing was changed.
Default configuration and new added switches will now work like intended.

When a controller is enabled (e.g. Domoticz MQTT or -HTTP) and the button is pressed multiple times, the ESP may reboot. See issue #674.
2018-01-05 17:03:44 +01:00
ESPEasy release bot d2e2522c07 automaticly updated release notes for mega-20180104 2018-01-04 03:13:01 +00:00
ESPEasy release bot 4a212302e0 changed date format of nightly builds 2018-01-03 14:51:40 +00:00
ESPEasy release bot 993dd7ade3 automaticly updated release notes for mega-01032018 2018-01-03 04:00:06 +00:00
Edwin Eefting e4d68b9d0e readme updates 2018-01-03 01:32:02 +01:00
Edwin Eefting b5e093bc80 changed readme title 2018-01-03 01:06:48 +01:00
Edwin Eefting d544fc84e8 changed readme to reflect mega branch and automated builds 2018-01-03 01:04:18 +01:00
Edwin Eefting e6dba4456c Merge branch 'v2.0' into mega 2018-01-03 00:52:03 +01:00
Edwin Eefting a0a0c31a49 updated travis link to reflect v2.0 2018-01-03 00:51:56 +01:00
Edwin Eefting d2777a9b15 updated travis link to reflect v2.0 2018-01-03 00:50:49 +01:00
Edwin Eefting c7d12bb798 Merge branch 'v2.0' into mega 2018-01-03 00:48:13 +01:00
Edwin Eefting 901d87ad1d updated readme to reflect new binary names 2018-01-03 00:47:35 +01:00
ESPEasy release bot ef912a4484 automaticly updated release notes for mega-01022018 2018-01-02 23:32:50 +00:00
ESPEasy release bot b4debd9559 created releasebot script 2018-01-02 23:30:53 +00:00
Edwin Eefting d7277649dd merged v2.0 branch. disabled memory checker (takes too long, perhaps enable it via a commit keyword?) 2018-01-03 00:28:22 +01:00
Edwin Eefting 33ec7e5240 Merge branch 'v2.0' into mega 2018-01-02 12:49:55 +01:00
Gijs NoorlanderandDatuX d62b692b3b [SDS011] Allow the sensor to sleep to extend sensor lifetime (#668)
* [SDS011] Add send commands to sensor

In the library used to communicate to the SDS011 sensor was only support to receive data from the sensor and not query the sensor or set another mode.
This is needed for #499 , to let the sensor sleep.

N.B. code is not yet tested, only implemented while reading the datasheet "Laser Dust Sensor Control Protocol V1.3"

* [SDS011] Lessen load on ESP by polling less frequent and use SoftSerial

The default setting were to set the delay to 0 and use an own software serial implementation.
This caused frequent timeouts on the web interface, WiFi reconnects, etc.
Now the already present SoftSerial is being used. This will gather all the data from the serial port and thus there is no need to poll 50 times a second.
Now the ESP is much more responsive.

* [SDS011] Allow the sensor to sleep to extend sensor lifetime

The internal laser of the SDS011 only will last for about 1 year when ran continuously.
When the RX of the sensor is connected, it can be set to sleep for N minutes between measurements. This will extend the lifetime of the sensor and reduce power consumption.
This sleep time is stored inside the flash of the sensor, so it can be set once and then the RX on the sensor could be disconnected again to be used for other purposes.
2018-01-02 12:22:57 +01:00
paulv888andDatuX 493bfd56b9 usesID = true (#666)
fixes #646
2018-01-02 11:41:01 +01:00
krikkandDatuX abbfa24ca6 added support for the TSL2591 Sensor based on Adafruit Library (#661)
* initial support for TSL2591 sensor

* return lux, visible, ir and full light separately

* better plugin init

* check sensor initialization before reading it..

* incorporated a few pending fixes for the adafruit library

* minor typo
2017-12-31 15:35:44 +01:00
Gijs NoorlanderandDatuX fae1edc859 [Security] Add IP-based filtering to web interface and http-commands. (#653)
* [mega] Detect client IP for SysInfo page and some cleanup

Added formatIP functions for readability and add client IP to SystemInfo page as preparation to detect origin just to get an idea of possibilities for #647.
Also added some reserve() statements to Strings to prevent heap fragmentation.

* [mega] Cleanup formatIP calls

* [security] #647 Add IP filtering to web interface and commands

As discussed in #647:
In the Config tab, a "Client IP filtering" section is added.
This allows for 3 levels of IP filtering:
* "Allow All" - does not imply any filtering based on IP address of the client.
* "Allow Local Subnet" - Allow only clients from within the local subnet, based on IP and subnetmask of the ESP.
* "Allow IP range" - Allow only clients within a range of IP-addresses.

Settings like these are very likely to lock out the rightful owner, so there are also two commands added, which can be sent via the serial connection.
* accessinfo
* clearaccessblock

The first one just displays the current active IP filtering.
The "clearaccessblock" command will temporarily disable the access filtering. This allows the user to login and reset the access filtering.

"Allow Local Subnet" is set as factory default.
Only when first loading a new firmware with this feature and existing configuration, the "All Allowed" is active (the old default)
2017-12-31 15:31:20 +01:00
s0170071andDatuX a9a741f775 fix chunking (#649)
* change chunking 

so that manual chunking is only done with core 2.3.0. 2.4.0rc2 and later do chunking web transfer implicitly

* Update WebServer.ino
2017-12-28 20:16:03 +01:00
Edwin Eefting c0d482e4fc merged v2.0 fixes 2017-12-28 19:01:16 +01:00
Bartłomiej ZimońandDatuX b5cabdc775 Update _C002.ino (#645)
related to #636
2017-12-18 23:14:11 +01:00
Gijs NoorlanderandDatuX c71a43c3a6 Reduce iRAM usage for plugins using SoftwareSerial (#631)
* [addLib] Added SoftwareSerial library

Added latest version from: https://github.com/plerup/espsoftwareserial

* [renLib] Renamed files to avoid conflicts with existing code

* [renLib] Changed include according to rename

* [renLib] Renamed all occurences and includes and removed unused pins

Renamed to make sure all plugins use the 'new' ESPeasySoftwareSerial.
Also added pinToIndex function to reduce memory footprint with about 150 Bytes, as described in issue #630

* [unused pins] Adjust indices in object list

Forgot to change the indices in the object list of SoftwareSerial

* Simple patch for timeouts

As mentioned in this issue: https://github.com/plerup/espsoftwareserial/issues/54

* [SoftSerial] Set ObjList static

Set the object list static to share all SoftwareSerial iRAM used as described in #630

* [revertLib] Revert to old version lib, since new version uses more iram

Just to test with old version, originally available in 2.3.0 library, to see if memory usage improves.

* [test] Reduce number of ports to 1 and lower buffer size to 18 for MHZ19

Just as a test, to see what happens to the iRAM usage, lower the number of concurrent softserial ports to 1.
Also the default buffer size = 64 Bytes. The MH-Z19 sensor can do with less, since a response will be up to 9 bytes, a 18-byte buffer allows for 2 messages to be stored.

* Enable usage of up to 10 concurrent softserial and reduce variable sizes

Re-enable use of up to 10 concurrent software serials.
Also reduce the variable sizes to smaller ranges. (e.g. uint8 instead of int)

* [test] Limit number of concurrent software serial devices

Earlier tests show the amount of iRAM used is somewhat related to the maximum number of allowed software serial ports.
In this test it is set to 3 and they are assigned through first come first served a slot.
2017-12-18 22:02:53 +01:00
Edwin Eefting cd01283ac6 Merge branch 'v2.0' into mega 2017-12-18 21:26:06 +01:00
M0ebiu5andDatuX 7ce1077bd6 P022_PCA9685 added change frequency - P038_NeoPixel added RGBW strips (SK6812) (#638)
* added change frequency

* rgbw test

* PCA9685 change frequency

* Cleanup RGBW implementation

* Added instructions
2017-12-18 21:18:39 +01:00
DaMandDatuX f9701d1c7b [Domoticz HTTP] Compatibility fix for BMP280 (#636) 2017-12-18 21:13:34 +01:00
GrovkillenandDatuX e764830113 Updated "/pinstates" page: Made the plugin number column display "P001" instead of "1" and "P012" instead of "12". 2017-12-18 21:11:00 +01:00
GHolliandDatuX 9646457b50 Cosmetics: fixing typos. (#628)
* Optimisation: save RAM.

* Another RAM optimisation (freeing RAM by moving static data from RAM to program memory).

* Fixing user-visible typos.

* Fixing typos in variables and comments.

* Fixing typos in comments.

* Revert changes of other pull request.
2017-12-08 14:18:24 +01:00
GrovkillenandDatuX 7346e55e0d Updated ESPTOOLS.exe from 0.4.6 to 0.4.12 (#627)
* Add files via upload

* Add files via upload

* Updated ESPTOOLS.exe from 0.4.6 to 0.4.12

See releases here: https://github.com/igrr/esptool-ck/releases
2017-12-08 13:57:04 +01:00
fensoftandDatuX ae38a8cb4f added #define FEATURE_SD (permit a flash size reduction of ~10k) (#568) 2017-12-08 13:56:13 +01:00
Sen HaerensandDatuX df46a4a5fc Enhanced system info layout (#624)
* Enhance sysinfo page layout

* Added hex notation for chip IDs

* Fixed comment
2017-12-08 13:48:17 +01:00
GrovkillenandDatuX 7c6797a141 Move "TTP229 keypad" and "Encoder" plugin from "testing" to "normal" (#619)
* Add files via upload

* Add files via upload
2017-12-04 21:58:25 +01:00
mvdbro 83abac8c5e Fix #599 2017-12-03 15:13:29 +01:00
s0170071andDatuX 5ba6b2f335 split IP addrress (#605)
The system variable %ip% truncates the last octet or so when printed on small displays. Now there are four new variables %ip1%, %ip2%... so that the octet printout can be distibuted across two lines.
2017-11-23 19:04:59 +01:00
Edwin Eefting 0d4ba7c6f1 testing for ds18b20 2017-11-22 03:35:29 +01:00
Edwin Eefting a1fc351183 fix #588. parseTemplate() now only checks enabled taskes for [] macros 2017-11-22 03:33:34 +01:00
GrovkillenandDatuX 33a6c39fc4 Changed bin file names to be more descriptive. (#597)
* Changed bin file names to be more descriptive.

* Fixed TRAVIS check
2017-11-21 23:40:19 +01:00
papperoneandDatuX f853f6ef25 deleted GPIO notes referring to 75HC595 not supported (#591) 2017-11-20 22:52:01 +01:00
Edwin Eefting 7a2d114360 fix illegal string manipulations in PLUGIN_WRITE for some plugins. fixes #347 and #460 2017-11-16 03:01:14 +01:00
Edwin Eefting 0157f387ee Merge branch 'v2.0' into mega 2017-11-16 02:02:22 +01:00
sakinitandDatuX c23be231e1 Fix p1 wifi gateway module (#587)
* Fix receiving illegal characters using Domoticz

* Update P1GatewayServer life-cycle
2017-11-16 00:24:34 +01:00
Gijs NoorlanderandDatuX 00f5c36919 [P039 Thermocouple] Handling negative values and proper error logging (#586)
Cppcheck warned for 'suspicious code':
[src\_P039_Thermocouple.ino:254]: (warning) Suspicious code: sign conversion of -1 in calculation because '-1' has a negative value

I agree with cppcheck that the code is at least suspicious and probably compiler dependent.
So in order to let cppcheck no longer output a warning and make it a bit more readable, I made this change.

Also added logs to indicate errors reported by the sensor.
2017-11-16 00:05:23 +01:00
Edwin Eefting c960175ec1 set lcd to NULL by default. #584 2017-11-15 23:57:01 +01:00
Gijs NoorlanderandDatuX e456604436 [LCD plugin] Added check of LCD object before dereferencing it (#584)
Possible fix for #581.
Just looking at the description of the problem, this may be causing the crashes,since the commands may be trying to dereference the LCD pointer while it still is NULL.
2017-11-15 23:55:29 +01:00
GrovkillenandDatuX ac4657e77f Added categories... (#552) 2017-11-14 21:28:53 +01:00
papperoneandDatuX 3817427e79 Update _P073_7DGT.ino (#553) 2017-11-13 00:49:28 +01:00
Edwin Eefting 0200b3c63e fix travis build errors. disable cpp checking for now 2017-11-13 00:26:21 +01:00
Edwin Eefting 972a1a5703 Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega 2017-11-12 23:10:27 +01:00
mvdbro 73c22176b8 ESP32 fixed chunked HTTP transfer 2017-11-05 09:19:26 +01:00
mvdbro 4db036f350 ESP32 fix UDP instability 2017-11-04 17:15:24 +01:00
mvdbro 52223f0a20 ESP32 Enabled OTA 2017-11-04 10:38:14 +01:00
mvdbro 907ad0faf6 ESP32 fix FreeRAM reporting 2017-10-29 14:34:46 +01:00
mvdbro 887e10c947 ESP32 Rules/ADC/PWM 2017-10-28 16:07:00 +02:00
mvdbro b4c463e452 ESP32 IRAM/Deepsleep 2017-10-27 17:04:45 +02:00
mvdbro 66ba9b1f46 First preparations for ESP32 2017-10-25 16:10:16 +02:00
Edwin Eefting 7db50811ba esptest stuff 2017-10-23 20:44:23 +02:00
Edwin Eefting 17d20705ff smooth out testing code 2017-10-23 00:44:00 +02:00
Edwin Eefting e3bd782a42 test fixes 2017-10-22 23:20:07 +02:00
Edwin Eefting b073379fff fixed bug in oled upstream lib 2017-10-16 17:29:26 +02:00
Edwin Eefting b89d8ff946 fix warnings 2017-10-16 17:19:48 +02:00
Gijs NoorlanderandDatuX 22ad971c8e Support both SSD1306 and SH1106 OLED in OLED_Framed plugin (#509)
* [SSD1306] Upgrade library to version 3.0

The library at https://github.com/squix78/esp8266-oled-ssd1306 has to be initialized differently in version 3.0

Known issue: The font for 3 lines is not working, so temporary used the same font as for 4 ilnes. The online font generator is currently unavailable at http://oleddisplay.squix.ch/

* OLED framed improve header footer

The header now has better visible WiFi bars indicator and alternates the device name and the connected WiFi SSID.

The bottom part now only shows dots for the pages with visible data instead of the maximum number of pages possible.

* [SSD1306] Upgrade library to version 3.2.7

Forgot to commit deletion of obsolete files in previous commit.

* [SSD1306] Added 12pt font for version 3.x of the library

The font generator is online again: http://oleddisplay.squix.ch/#/home 
Added Dialog Plain 12 font for the 3-line display mode.

* [OLED_Framed] Allow to use either SSD1306 or SH1106

The new OLED library  allows to use SH1106 and SSD1306 controler.
Added support for both with an selector to select the available controler.

* [OLED_Framed] Only destruct and construct display object when changed

* [OLED Framed] Add contrast setting to display

Both SSD1306 and SH1106 support setting the contrast.

* Update _P036_FrameOLED.ino
2017-10-16 16:55:22 +02:00
Edwin Eefting ab06cc3703 merged v2.0 fix for MHZ19 (was already fixed in a different way) 2017-10-16 01:54:37 +02:00
Edwin Eefting 8a5cc5f2bd fix plugin id (starting with a 0 makes it octal in c++ :( ) 2017-10-16 01:47:57 +02:00
papperoneandDatuX 6919baf23c Plugin 073 - 7-segment display plugin TM1637/MAX7219 2017-10-16 01:44:56 +02:00
Gijs NoorlanderandDatuX ddedb215c4 [MH-Z19] Allow for B-version and add filtering (#525)
* [MH-Z19] Allow for B-version and add filtering

The "B" version of the sensor does not output an S value, but does internally apply a dynamic response filter on the samples based on the amount of fluctiation in the data.
The implemented filter does something similar for the "A" version and for both adds the option for an extra delay filter to smooth the data.

Default filter setting ("off") is the old behavior, where only stable values are allowed.

* [MH-Z19] Improve label texts and logging

The first commit for the filtering had some confusing text labels.
Also it would be nice to see the effect of filtering in the logs.
2017-10-16 01:36:43 +02:00
Tomasz TorczandDatuX 08d4d817f6 retain MQTT LWT messages (#516)
Retaining will messages allows monitoring agent to receive full info about clients state.
Without retaining, the monitoring agent will only be informed about events (connect/connection lost) happening during agent's connection to broker. Any reconnect would cause monitoring agent to lose state.
2017-10-16 01:18:45 +02:00
Edwin Eefting e8bdcfbaf2 keep TASKS_PER_PAGE at default value of 4 2017-10-16 01:16:55 +02:00
Edwin Eefting 743fb4494e improvement: Configurable number of tasks for "Devices" page #510
(by hexenmeister)
2017-10-16 01:15:34 +02:00
MichaelandDatuX 0a4bc7fad6 src/Hardware.ino: make it possible to use GPIO-0 (D3) as Pin_sd_cs (#508) 2017-10-16 01:04:12 +02:00
MichaelandDatuX 49d0b16324 WebServer.ino: enhance handle_SDfilelist() (#507) 2017-10-16 01:03:42 +02:00
Gijs NoorlanderandDatuX de479d6188 [SSD1306] Feature/oled 1306 library upgrade (#501)
* [SSD1306] Upgrade library to version 3.0

The library at https://github.com/squix78/esp8266-oled-ssd1306 has to be initialized differently in version 3.0

Known issue: The font for 3 lines is not working, so temporary used the same font as for 4 ilnes. The online font generator is currently unavailable at http://oleddisplay.squix.ch/

* OLED framed improve header footer

The header now has better visible WiFi bars indicator and alternates the device name and the connected WiFi SSID.

The bottom part now only shows dots for the pages with visible data instead of the maximum number of pages possible.

* [SSD1306] Upgrade library to version 3.2.7

Forgot to commit deletion of obsolete files in previous commit.

* [SSD1306] Added 12pt font for version 3.x of the library

The font generator is online again: http://oleddisplay.squix.ch/#/home 
Added Dialog Plain 12 font for the 3-line display mode.
2017-10-16 01:00:30 +02:00
Gijs NoorlanderandDatuX 3fd3e13dc7 OLED framed improve header footer (#495)
The header now has better visible WiFi bars indicator and alternates the device name and the connected WiFi SSID.

The bottom part now only shows dots for the pages with visible data instead of the maximum number of pages possible.
2017-10-16 00:55:25 +02:00
BadWolf42andDatuX d7d913d439 Dallas Plugin enhanced : no more "delay()" (#488)
* Enhanced Dallas pooling to avoid use of delay(800)

DS_readTemp has been split in 2: DS_convertTemp and DS_readonlyTemp.
DS_convertTemp is first called after DS_setResolution.
Then DS_convertTemp is called after temp has been read.
DS_readTemp has been kept for compatibility.
The only downside is that you read the temperature of previous query (value set by Timer/TDT option).

* typo

* Moved to Environment + code cleaning

- Moved Plugin from Temperature to Environment
- Modified Plugin_004_DS_crc8 to check CRC8, not return it
- Renamed Plugin_004_DS_convertTemp to Plugin_004_DS_startConvertion and removed useless vars in it
- Removed unneed braces and empty lines
- Added comments
2017-10-16 00:51:05 +02:00
SightofSilenceandDatuX 5c4ae3820b Add System Variable for day, month and year / Fix for "Calculate" function to recognize minus-sign (#485)
* Add files via upload

* Update Misc.ino

* Add files via upload
2017-10-16 00:47:58 +02:00
Gijs NoorlanderandDatuX 38774a20c6 Single function for format to user defined number decimals (#482)
* Single function for format to user defined number decimals

In a number of files the same long definition was cut and paste a lot to format  values to a user defined number of decimals.

Now a new simple function is added to Misc to perform this formatting, which results in more clean code, less prone to errors and a reduction in use of resources.

* Single function for format to user defined number decimals

In a number of files the same long definition was cut and paste a lot to format  values to a user defined number of decimals.

Now a new simple function is added to Misc to perform this formatting, which results in more clean code, less prone to errors and a reduction in use of resources.
2017-10-16 00:42:14 +02:00
Gijs NoorlanderandDatuX 9fc58bb4df P028 to support both BME280 and BMP280 to reduce resource usage (#481)
* P028 now supports both BME280 and BMP280

Both plugins P028 and P030 had a lot of code duplication. This takes up resources and is hard to maintain.
Now the P028 plugin can detect and use both sensors so P030 may be removed.

Only caveat is that the BMP280 does not measure humidity and thus actually is a 2-value sensor. The Domotics MQTT controller did not distinguish between them, but other controllers may do so.
When needed, the P030 plugin can still be a mere stub for the output and plugin definition and still share all code with P028.

* [BME280] Add temperature offset and improve read stability

The BME280/BMP280 may heat up internally if read too often and too long.
Also when built in a small container along with other sensors and the ESP, the sensor may read values which are too high.
To compensate for these higher readings, a constant offset may be applied in the device parameters.
This value is a signed integer value representing the offset in 1/10th degree Celsius.

Since the humidity is a relative value, depending on the temperature, this should be adjusted also.

Only this computed dew point temperature is also too high, due to the fact the sensor is warmer than the air and thus the perceived humidity is off.
To correct for this, half the offset temperature is being used to compute the dew point temperature.

The other improvement is the routine to read the sensor.

Using this routine, the sensor is only active for about 1.6 seconds each minute.
This prevents the sensor to heat up from its own readings and also allows stable readings using some filtering. (slamming a door does not affect the readings)

* [BMx280] Auto detect connected chip ID and show in Device config tab

Detect connected chip (BME280/BMP280) automatically and show detected device immediately in the Device config page next to the I2C address selection.

* [BME/BMP280] Perform reset at init

Just to make the reading a bit more stable when the sensor stops responding.
This is also done in the "official" Bosch github: https://github.com/BoschSensortec/BME280_driver

* [BMx280] Allow for more than one sensor 

As suggested in #491 for another sensor, its I2Caddress was handled incorrectly. The same applied to this plugin.
2017-10-16 00:27:04 +02:00
SloMustiandDatuX ca936ca42f implemewnted web activity timer tracker (#462) 2017-10-16 00:23:05 +02:00
Edwin Eefting 840fb6b647 Merge branch 'v2.0' into mega 2017-10-16 00:16:25 +02:00
denisfrenchandDatuX c80b5d6d78 Set MQTT clientid to %sysname% +/- Settings.Unit (#431) (#436) 2017-10-16 00:12:09 +02:00
hatzlhofferandDatuX 40067c514f added new display size 128x32 (#545)
added font size optimization
2017-10-16 00:06:59 +02:00
Alexander Schulz 139ae36d3e improvement: Configurable number of tasks for "Devices" page (TASKS_P…
…ER_PAGE)
2017-09-16 23:24:15 +02:00
184 changed files with 20056 additions and 7310 deletions
+5 -4
View File
@@ -1,9 +1,10 @@
# cmd: "cd {PROJECT_PATH}; platformio"
cmd: "platformio"
name: "Build with error highlighting (dev_4096)"
name: "Build with error highlighting (dev_ESP8266_4096)"
args:
- run --environment dev_4096
sh: true,
cwd: .
- run --environment dev_ESP8266_4096
sh: true
cwd: "{PROJECT_PATH}"
# env:
# VARIABLE1: "VALUE1"
# VARIABLE2: "VALUE2"
+3 -1
View File
@@ -26,6 +26,8 @@ Also there are more people on the forum that can help you with support.
* 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.
* Do not modify any of the variables passed to your PLUGIN_WRITE handler.
* New plugins that seem to be working correctly should have a PLUGIN_BUILD_TESTING around until they are tested enough. Also add [TESTING] to the name
* Also see our general guidelines at: https://www.letscontrolit.com/wiki/index.php/ESPEasyDevelopmentGuidelines
+1
View File
@@ -4,3 +4,4 @@
.piolibdeps
lib/readme.txt
src/Custom.h
+6 -1
View File
@@ -25,10 +25,15 @@ install:
- pip install -U platformio
script:
- cppcheck --enable=warning src/*.ino -q --force -I src --include=src/ESPEasy.ino --error-exitcode=1
# - 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_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -s
# patch platformio core libs for PUYA bug (https://github.com/letscontrolit/ESPEasy/issues/650)
- cd patches; ./check_puya_patch; cd ..
- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -s --environment dev_ESP8266PUYA_1024
before_deploy:
- ./before_deploy
- export RELEASE_FILE=$(ls ESPEasy*.zip)
+20 -24
View File
@@ -1,43 +1,39 @@
# ESPEasy (mega branch)
# ESPEasy (development branch)
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.
**MEGA**
:warning:This is the development branch of ESPEasy. All new untested features go into this branch. If you want to do a bugfix, do it on the stable branch, we will merge the fix to the development branch as well.:warning:
Next stable branch: https://github.com/letscontrolit/ESPEasy/tree/v2.0 (bug fixes only, since oct 2017))
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.
## Automated binary releases
## Firmware binary releases
Every night our build-bot will build a new binary release: https://github.com/letscontrolit/ESPEasy/releases
Binary development releases are here: https://github.com/letscontrolit/ESPEasy/releases
The releases are named something like 'mega-20180102' (last number is the build date)
Depending on your needs, we release different types of files.
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 |
Firmware name | Hardware | Included plugins |
----------------------------------------------|-------------------------|-----------------------------|
ESPEasy_mega-20180102_normal_ESP8266_1024.bin | ESP8266 with 1Mb flash | Stable |
ESPEasy_mega-20180102_test_ESP8266_1024.bin | ESP8266 with 1Mb flash | Stable + Test |
ESPEasy_mega-20180102_dev_ESP8266_1024.bin | ESP8266 with 1Mb flash | Stable + Test + Development |
ESPEasy_mega-20180102_normal_ESP8266_4096.bin | ESP8266 with 4Mb flash | Stable |
ESPEasy_mega-20180102_test_ESP8266_4096.bin | ESP8266 with 4Mb flash | Stable + Test |
ESPEasy_mega-20180102_dev_ESP8266_4096.bin | ESP8266 with 4Mb flash | Stable + Test + Development |
ESPEasy_mega-20180102_normal_ESP8285_1024.bin | ESP8285 with 1Mb flash | Stable |
ESPEasy_mega-20180102_test_ESP8285_1024.bin | ESP8285 with 1Mb flash | Stable + Test |
ESPEasy_mega-20180102_dev_ESP8285_1024.bin | ESP8285 with 1Mb flash | Stable + Test + Development |
## 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
+25 -14
View File
@@ -1,24 +1,32 @@
#!/bin/bash
VERSION=$(git describe)
echo "Creating release archives for $VERSION ..."
#binaries
#ESP_Easy_v[version]-[build type]-dev[dev number]-ESP[chip type]-[size].bin
#Naming convention:
# ESP_Easy_[github version]_[plugin set]_[chip type]_[flash memory].bin
#cp .pioenvs/mini_512/firmware.bin dist/"ESPEasy_$VERSION""_mini_512.bin"
cp .pioenvs/normal_ESP8266_1024/firmware.bin dist/"ESP_Easy_$VERSION""_normal_ESP8266_1024.bin"
cp .pioenvs/normal_ESP8266_4096/firmware.bin dist/"ESP_Easy_$VERSION""_normal_ESP8266_4096.bin"
cp .pioenvs/normal_ESP8285_1024/firmware.bin dist/"ESP_Easy_$VERSION""_normal_ESP8285_1024.bin"
for ENV in \
normal_ESP8266_1024 \
normal_ESP8266_4096 \
normal_ESP8285_1024 \
test_ESP8266_1024\
test_ESP8266_4096\
test_ESP8266_4096_VCC\
test_ESP8285_1024\
dev_ESP8266_1024\
dev_ESP8266_4096\
dev_ESP8285_1024\
dev_ESP8266PUYA_1024\
dev_ESP8266PUYA_1024_VCC;\
do
echo
echo "### Deploying environment $ENV for version $VERSION"
BIN=.pioenvs/$ENV/firmware.bin
python2 crc2.py $BIN
cp $BIN dist/"ESP_Easy_$VERSION""_$ENV.bin"
done
cp .pioenvs/test_ESP8266_1024/firmware.bin dist/"ESP_Easy_$VERSION""_test_ESP8266_1024.bin"
cp .pioenvs/test_ESP8266_4096/firmware.bin dist/"ESP_Easy_$VERSION""_test_ESP8266_4096.bin"
cp .pioenvs/test_ESP8285_1024/firmware.bin dist/"ESP_Easy_$VERSION""_test_ESP8285_1024.bin"
cp .pioenvs/dev_ESP8266_1024/firmware.bin dist/"ESP_Easy_$VERSION""_dev_ESP8266_1024.bin"
cp .pioenvs/dev_ESP8266_4096/firmware.bin dist/"ESP_Easy_$VERSION""_dev_ESP8266_4096.bin"
cp .pioenvs/dev_ESP8285_1024/firmware.bin dist/"ESP_Easy_$VERSION""_dev_ESP8285_1024.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
@@ -28,4 +36,7 @@ cp -r src dist/Source/
cp platformio.ini dist/Source/
cd dist
echo
echo "### Creating zip archive"
zip ../ESPEasy_$VERSION.zip -r .
+116
View File
@@ -0,0 +1,116 @@
import sys
import binascii
import struct
import md5
import os
MD5DUMMY = "MD5_MD5_MD5_MD5_BoundariesOfTheSegmentsGoHere..." #48 chars
FILENAMEDUMMY = "ThisIsTheDummyPlaceHolderForTheBinaryFilename..." #48 chars
MemorySegmentStart,MemorySegmentEnd,MemoryContent=[],[],[]
##################################################################
# this subroutine shows the segments of a part
##################################################################
def showSegments (fileContent,offset):
global MemorySegmentStart, MemorySegmentEnd, MemoryContent
header = struct.unpack("ii", fileContent[offset:offset+8])
herestr =""
herestr2 =""
MemorySegmentStart.append(struct.pack("I",header[0]))
MemorySegmentEnd.append(struct.pack("I",header[0]+header[1]))
MemoryContent.append(fileContent[offset+8:offset+8+header[1]])
if fileContent.find( MD5DUMMY, offset+8, offset+8+header[1]) >0 :
herestr= " <-- CRC is here."
if fileContent.find( FILENAMEDUMMY, offset+8, offset+8+header[1]) >0 :
herestr2= " <-- filename is here."
print ("SEGMENT "+ str(len(MemorySegmentStart)-1)+ ": memory position: " + hex(header[0])+" to " + hex(header[0]+header[1]) + " length: " + hex(header[1])+herestr+herestr2)
#print ("first byte positoin in file: " + hex( offset+8))
#print ("last byte postion in file: " + hex(offset+8+header[1]-1))
return (8+offset+ header[1]); # return start of next segment
##################################################################
# this subroutine shows the parts of a binary file
##################################################################
def showParts(fileContent, offset):
header = struct.unpack("BBBBi", fileContent[offset:offset+8])
print ('\n\nBINARY PART\nSegments: ') + (hex(header[1]))
nextpos =offset+8
for x in range (0,header[1]):
nextpos = showSegments(fileContent,nextpos)
nextSegmentOffset = (fileContent.find("\xe9", nextpos))
return nextSegmentOffset
##################################################################
# MAIN
##################################################################
#if len(sys.argv) !=2 :
# print ("please give a filename")
# k=input("press close to exit")
# sys.exit(1)
FileName = sys.argv[1]#"C:/ArduinoPortable/sketchbooks/build/sketch_jan15a.ino.bin"
#FileName = "C:/ArduinoPortable/sketchbooks/build/sketch_jan15a.ino.bin"
print( "\n\nReplacing dummy MD5 checksum in .bin file")
with open(FileName, mode='rb') as file: # b is important -> binary
nextpos =0;
fileContent = file.read()
while nextpos >=0:
nextpos = showParts(fileContent,nextpos)
startArray,endArray,hashString = "","",""
includeStr = "hash includes segments:"
# memory sections:
# 0: bootloader (not readable)
# 1: program memory (SPI flash)
# 2: unknown but stable
# 3: RAM (initialized by bin file. Can be read but changes as you go :-( )
# 4: RAM
for i in (1,2 ): # use only stable segments, must be 4 in total. We use 2.
startArray =startArray + MemorySegmentStart[i]
endArray = endArray + MemorySegmentEnd[i]
hashString =hashString + MemoryContent[i]
with open(FileName+str(i), mode='wb') as file: # b is important -> binary
file.write(MemoryContent[i])
includeStr = includeStr +" "+ str(i)
print (includeStr)
# IMPORTANT: pad array with zeros if you use only 3 segments (see above)
while len(startArray) < 16 :
startArray =startArray + struct.pack("I",0)
endArray = endArray + struct.pack("I",0)
# debug print (binascii.hexlify(startArray))
# debug print (binascii.hexlify(endArray))
if (len(endArray) + len (startArray)) != 32 :
print("ERROR: please make sure you add / remove padding if you change the semgents.")
BinaryFileName = "";
if fileContent.find( FILENAMEDUMMY) < 0:
print("ERROR: FILENAMEDUMMY dummy not found in binary")
else:
BinaryFileName=os.path.basename(FileName) +"\0"
if len(BinaryFileName) >48: # check that filename is <48 chars
BinaryFileName=BinaryFileName[0:48] # truncate if necessary. 49th char in ESP is zero already
else:
BinaryFileName= BinaryFileName.ljust(48,'\0'); # pad with zeros.
if fileContent.find( MD5DUMMY) < 0:
print("ERROR: MD5 dummy not found in binary")
else:
hashString=hashString.replace (MD5DUMMY,"",1)
m = md5.new()
m.update (hashString) #use segment 1
md5hash = m.digest()
print("MD5 hash: "+ m.hexdigest())
print("\nwriting output file:\n" + FileName)
fileContent=fileContent.replace(MD5DUMMY,md5hash+startArray+endArray)
fileContent=fileContent.replace(FILENAMEDUMMY,BinaryFileName)
with open(FileName, mode='wb') as file: # b is important -> binary
file.write(fileContent)
#k=input("press close to exit")
+945
View File
@@ -1,3 +1,948 @@
-------------------------------------------------
Changes in release mega-20180304 (since mega-20180303)
-------------------------------------------------
Release date: Sun Mar 4 04:00:08 CET 2018
Bartlomiej Zimon (4):
- pcfgpio,port,2 sets pin as input - fix for #222,#702 - we can mix inputs and outputs now
- extend conditions with AND/OR, now it is possible to simplify rules
- remove Serial print
- support for more comparisions in IF conditions: >=,<=,!=,<>,<,>,= also fix extended conditions when first check is not >
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180303
Gijs Noorlander (2):
Merge pull request #1000 from uzi18/test3 (more comparisions in IF condition)
_P072_HDC1080 allow to send values to the controllers (#999)
Unknown (2):
[issue #993] Add %unit% variable in MQTT subscribe topic
[issue #892 ] Only use sensor type when really needed
clumsy-stefan (1):
add success and break statement
mvdbro (1):
ESP32 Dallas DS18B20 fix
soif (1):
Fixes P073 plugin for latest TM1637 based 7 segments displays modules
-------------------------------------------------
Changes in release mega-20180303 (since mega-20180302)
-------------------------------------------------
Release date: Sat Mar 3 04:00:08 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180302
Unknown (5):
revert json to non-chunking #988 from s0170071/mega
[issue #293] json output nan values not double quoted
Add Task device type to json by @s0170071
[Issue #827] MQTT not using proper case for %sysname% variable.
Add AND/OR to rules & prevent unwanted case changes in strings (#994)
s0170071 (3):
revert json to non-chunking
Add git build and local time
make handle_json return void
-------------------------------------------------
Changes in release mega-20180302 (since mega-20180228)
-------------------------------------------------
Release date: Fri Mar 2 04:00:10 CET 2018
Bartłomiej Zimoń (4):
provide System@Sleep event (#875)
add format #O to templates to show OFF/ON instead 0/1 (#949)
fix #964, add timeStringToSeconds and use it to compare time conditions (#965)
add format #O to templates to show OFF/ON instead 0/1 (#949)
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180228
Gijs Noorlander (1):
Merge pull request #983 from kahvm/mega
Unknown (4):
[issue #914] _P053_PMSx003 Dust Sensor looses sync
[issue #914] Check first 2 bytes of packet
[Build error fix] Must-keep-focus-when-pressing-buttons...
[webserver] Layout of code to improve readability
kahvm (1):
Support for degree sign on LCD1602
mvdbro (2):
Rule wildcard option on literal events
Rule wildcard option on literal events
s0170071 (1):
Add Factory Reset button to web interface (#954)
-------------------------------------------------
Changes in release mega-20180228 (since mega-20180227)
-------------------------------------------------
Release date: Wed Feb 28 04:00:09 CET 2018
Bartłomiej Zimoń (1):
fix #964, add timeStringToSeconds and use it to compare time conditions (#965)
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180227
Gijs Noorlander (2):
[issue #966] Add %sysweekday% and %sysweekday_s% (#973)
[issue #968] Use template parser for OLED commands (#974)
-------------------------------------------------
Changes in release mega-20180227 (since mega-20180226)
-------------------------------------------------
Release date: Tue Feb 27 04:00:11 CET 2018
Bartłomiej Zimoń (1):
add format #O to templates to show OFF/ON instead 0/1 (#949)
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180226
Edwin Eefting (2):
[test suite] changes from mega to 2.0
[test suite] changes from mega to 2.0
Gijs Noorlander (2):
[BuildError] StreamingBuffer code cleanup + fix order member initialize (#961)
[build conflict] Renamed ESP32 version of ping (#963)
mvdbro (1):
Fix ESP32 compile errors
s0170071 (1):
Add Factory Reset button to web interface (#954)
-------------------------------------------------
Changes in release mega-20180226 (since mega-20180224)
-------------------------------------------------
Release date: Mon Feb 26 04:00:08 CET 2018
Bartłomiej Zimoń (2):
provide System@Sleep event (#875) (#931)
- extend conditions with AND/OR, now it is possible to simplify rules (#932)
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180221
Edwin Eefting (1):
device page doesnt need next/previous page buttons anymore
Gijs Noorlander (7):
[MQTT] LWT "Connected" message doesn't have the retained flag (#925)
[v2.0] Added Vcc-binaries to deploy process #933 (#935)
[v2.0 merge] 2kwebserver_merge_to_mega #929 (#934)
[v2.0] Use ESPeasySoftwareSerial (#936)
[Mega] rename SoftwareSerial lib #930 (#937)
[timeouts] Improve response when hosts are not reachable (#939)
[2k Webserver] Proper initialisation of StreamingBuffer members. (#941)
Michael Schröder (1):
Added Vcc-binaries to deploy process (#933)
Unknown (2):
[ping lib] Added ping library
[softwareSerial] Remove duplicate with only capilization as difference
s0170071 (33):
Webserver min memory
Adjusted to min 7k free
Timeout 100ms
tcp_cleanup for LWIP1 & 2
Adapted timeout
trigger travis re-compile
try fix travis
Does Travis like extern "C" ?
Wait for memory be like before send chunked
"Content-Type","text/html"
Optimized memory usage
2k Webserver
fix travis
fix travis
Unused variable
navMenuIndex
fix download page
Add Ram usage debug message
fix Travis
Travis...
Cleanup and +1k Ram
4->12 Devices per page
Fix travis
Update .gitignore
Merge Webserver
Fixed String redeclaration
Merge into mega
fix travis
Removed double entry on info page
Fix compile error when SD card is enabled
Memtracker (#927)
V20 Webserver@LowMemory
Update WebServer.ino
-------------------------------------------------
Changes in release mega-20180224 (since mega-20180223)
-------------------------------------------------
Release date: Sat Feb 24 04:00:06 CET 2018
mvdbro (2):
Fix ESP32 compile errors
ESP32 fixed P020 and P044
-------------------------------------------------
Changes in release mega-20180223 (since mega-20180221)
-------------------------------------------------
Release date: Fri Feb 23 04:00:07 CET 2018
GHolli (1):
* BugFix: According to the data sheet, the offset for the detection range values (command byte 0x99) is 3..4 instead of 6..7 (#921)
s0170071 (1):
Include name of binary file in crc2.py and sysinfo (#918)
-------------------------------------------------
Changes in release mega-20180221 (since mega-20180220)
-------------------------------------------------
Release date: Wed Feb 21 04:00:09 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180220
Edwin Eefting (3):
SENSOR_TYPE_TEMP_BARO changed, was probably implemented incorrectly before
apply PUYA patch to all available frameworks
[test suite] corrected PUYA test. added erase/build/flash for all chips. preparations for full automatic hardware regression testing
GHolli (1):
Optimisation: Save RAM (freeing RAM by moving static data from RAM to program memory). (#910)
Gijs Noorlander (1):
[issue #899 ] Backport of DHT22 implementation on Mega (#913)
Stanislav Mihic (1):
Frontend (#906)
-------------------------------------------------
Changes in release mega-20180220 (since mega-20180219)
-------------------------------------------------
Release date: Tue Feb 20 04:00:08 CET 2018
Bartłomiej Zimoń (1):
- pcfgpio,port,2 sets pin as input (#897)
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180219
Edwin Eefting (1):
function was moved to StringConverter.inp
Gijs Noorlander (3):
[isue #877] Add VCC enable firmware file to release list (#894)
[Cleanup] Move String manipulating functions to single file (#895)
[issue #893] Fix globalSync not working when no controllers active (#896)
Unknown (3):
[issue #847] Fix last letter of command is cut in OpenHAB MQTT
[Event Log] Add event name to event processing time log
[issue #899] DHT22 readings not received
-------------------------------------------------
Changes in release mega-20180219 (since mega-20180217)
-------------------------------------------------
Release date: Mon Feb 19 04:00:09 CET 2018
ESPEasy release bot (2):
automaticly updated release notes for v2.0-20180217
automaticly updated release notes for v2.0-20180218
Gijs Noorlander (4):
[issue #847 ] OpenHAB MQTT rewrite topic parser (#886)
[issue #885] MAC address as system variable (#887)
[Build Mega] Fix for Build Mega 20180217 (#889)
[issue #890] Split overlap for both Domoticz controllers to helper (#891)
-------------------------------------------------
Changes in release mega-20180217 (since mega-20180214)
-------------------------------------------------
Release date: Sat Feb 17 04:00:07 CET 2018
Bartłomiej Zimoń (1):
provide System@Sleep event (#875)
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180214
Gijs Noorlander (4):
[issue 866] Try to stop logging to serial when serial is not read. (#868)
[issue #853] Favicon.ico (#874)
[OLED Framed] ESP Easy logo (#876)
[issue #869] Added 'LWT' to last will topic and improved CPU load (#883)
-------------------------------------------------
Changes in release mega-20180214 (since mega-20180213)
-------------------------------------------------
Release date: Wed Feb 14 04:00:09 CET 2018
Bartłomiej Zimoń (1):
fix for Blynk Controller (#863)
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180213
Edwin Eefting (3):
workaround for PUYA flash chips with write issues #650
travis build fix for PUYA
updated deploy script for PUYA
Gijs Noorlander (1):
[v2.0] Blynk controller (#865)
-------------------------------------------------
Changes in release mega-20180213 (since mega-20180212)
-------------------------------------------------
Release date: Tue Feb 13 04:00:09 CET 2018
ESPEasy release bot (3):
automaticly updated release notes for v2.0-20180206
automaticly updated release notes for v2.0-20180209
automaticly updated release notes for v2.0-20180212
Edwin Eefting (1):
make blynk stuff compile again
Gijs Noorlander (10):
[Issue #831] Use DOUT flash mode (#834)
[#804] Degree symbol for non-framed OLED display (#835)
Blynk controler (re-implementation of PR#92) (#837)
[issue #839] Add command support for setting contrast for OLED Framed (#841)
[P001 Switch] Fix a mixup in previous fix for switch (#845)
[v2.0] Fix compile errors on ESP32 (#848)
Bugfix/oled framed less memory (#859)
Formatting user vars (re-do of PR#482) + enabled check OpenHabMQTT (#851)
[issue #825] Change labels and password form for Thingspeak controller (#849)
[MQTT] Allow for background tests while waiting for wifi (#860)
Henri de Jong (1):
Added support for pioneer ir signals (#844)
soif (2):
Add Device Name in /json page (#815)
P012 - Fix/handle lines exceeding LCD width + allow to clear line b4 print (#852)
wdonker (1):
Add trigger for rulesprocessing (#826)
-------------------------------------------------
Changes in release mega-20180212 (since mega-20180209)
-------------------------------------------------
Release date: Mon Feb 12 04:00:09 CET 2018
mvdbro (1):
Fix compile errors on ESP32
-------------------------------------------------
Changes in release mega-20180209 (since mega-20180206)
-------------------------------------------------
Release date: Fri Feb 9 04:00:15 CET 2018
Andrey (1):
Added HIGH-Z state options for GPIO command (#833)
-------------------------------------------------
Changes in release mega-20180206 (since mega-20180203)
-------------------------------------------------
Release date: Tue Feb 6 05:00:10 CET 2018
ESPEasy release bot (2):
automaticly updated release notes for v2.0-20180202
automaticly updated release notes for v2.0-20180203
Gijs Noorlander (3):
Backport OLED framed from mega + support special characters (#818)
[issue #817] Added mail header to SMTP (#820)
[issue #727] Proper user interface to set DST rules (#823)
Grovkillen (1):
Update README.md
s0170071 (1):
Add compile time (#811)
soif (1):
All Advanced Settings as 'DEFAULT_' Defines (#813)
-------------------------------------------------
Changes in release mega-20180203 (since mega-20180202)
-------------------------------------------------
Release date: Sat Feb 3 05:00:11 CET 2018
Grovkillen (1):
Update README.md
-------------------------------------------------
Changes in release mega-20180202 (since mega-20180130)
-------------------------------------------------
Release date: Fri Feb 2 05:00:12 CET 2018
DatuX (3):
Update README.md
Update README.md
Update README.md
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180130
Edwin Eefting (1):
Add CRC checks to all binaries when building a release with travis. fixes #779
Gijs Noorlander (4):
[Mega] Fix pointer arithmetic on void pointers for CRC computations (#795)
[issue #794] Add longpulse_ms command (#796)
[v2.0] Resource friendly string replacement (#798)
[issue #739] Reconnect MQTT when Unit Name has changed. (#803)
soif (5):
Fixes invalid '/json' page output format : DateTimeString is now correctly quoted (#802)
Fix Syslog : include Hosname instead of Unit Number - now RFC3164 compliant (#805)
Allows to define the IP address when in AP Mode (#806)
Custom define file (#807)
Json page also Shows Git Build (#808)
-------------------------------------------------
Changes in release mega-20180130 (since mega-20180126)
-------------------------------------------------
Release date: Tue Jan 30 05:00:12 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180126
Edwin Eefting (1):
forgot to commit last framed oled display fix
Gijs Noorlander (3):
Bugfix/issue 740 allow mqtt as controller 2 3 (#785)
[#784] Add %rssi% as system variable (#786)
[Log] Clean up of log routines and more intuitive log level input (#788)
-------------------------------------------------
Changes in release mega-20180126 (since mega-20180124)
-------------------------------------------------
Release date: Fri Jan 26 05:00:11 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180124
Gijs Noorlander (5):
[Mega] Allow compile with 2.4.0 core library (#772)
[issue #759] Disable Senseair ABC due to firmware issues (#771)
[V2.0] Allow IRremoteESP8266 to be built with core 2.4.0 (#773)
[Mega] Force 2.3.0 for all builds and add an option for 2.4.0 core (#775)
Update _C007.ino (#774) (#776)
josemariaaraujo (1):
Update _C007.ino (#774)
-------------------------------------------------
Changes in release mega-20180124 (since mega-20180123)
-------------------------------------------------
Release date: Wed Jan 24 05:00:09 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180123
Edwin Eefting (1):
fix #718. also update display on save and removed graphical boot logo to conserve space. also fixes #713. (web interface will be non repsonsive during scrolling now, but there is no easy fix for that)
Gijs Noorlander (1):
[issue #758] P029 MQTT helper does not log anymore (#764)
s0170071 (2):
Broken comment (#766)
Space (#767)
-------------------------------------------------
Changes in release mega-20180123 (since mega-20180122)
-------------------------------------------------
Release date: Tue Jan 23 05:00:10 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180122
Edwin Eefting (5):
test suite: now possible to run all tests at once. fixes
test suite: espcli can now do stuff for all configured nodes
clear custom task and controller settings when selecting a different device or protocol. replaces #762 . fixes #721
added easy reboot warning and function to work around several issues
request mainpage when checking if reboot is complete
Gijs Noorlander (1):
Central function for system variable replacement (#757)
s0170071 (1):
CRC on settings and security settings and progmem (#720)
-------------------------------------------------
Changes in release mega-20180122 (since mega-20180119)
-------------------------------------------------
Release date: Mon Jan 22 05:00:08 CET 2018
ESPEasy release bot (3):
automaticly updated release notes for v2.0-20180119
automaticly updated release notes for v2.0-20180120
automaticly updated release notes for v2.0-20180121
Edwin Eefting (8):
test suite: added dht22
added QUAD to c002. fixed getBearing and SENSOR_TYPE_WIND.
test suite: started on testcase to test all sensor types via the dummy plugin
test suite: generelized controller testing in test005
cleaned up nodo logging. fixed domotics SENSOR_TYPE_WIND inconsistency
test suite: fixed issues, started working on nodo
test suite: lots of refactoring and fixing
test suite: fixes. testing boot gpio states
Gijs Noorlander (2):
[issue #745] Set IPaddress to 0.0.0.0 when read from empty string (#754)
[#732] Only process P029 MQTT helper when enabled (#743)
-------------------------------------------------
Changes in release mega-20180119 (since mega-20180118)
-------------------------------------------------
Release date: Fri Jan 19 05:00:07 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180118
Edwin Eefting (2):
refactoring test suite controller stuff
test suite domoticz mqtt + found few fixmes
jctual (1):
DHT plugin update (#736)
-------------------------------------------------
Changes in release mega-20180118 (since mega-20180117)
-------------------------------------------------
Release date: Thu Jan 18 05:00:07 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180116
Edwin Eefting (3):
made test resumable and importable
now supports powercycle to test for bugs like #719
added fixme
Gijs Noorlander (2):
[issue 733] Fix for negative values on MQTT import (#735)
[issue 728] Proper reconnect for MQTT controllers (#737)
-------------------------------------------------
Changes in release mega-20180117 (since mega-20180116)
-------------------------------------------------
Release date: Wed Jan 17 05:00:08 CET 2018
Edwin Eefting (1):
fix #719 (initial ds18b20 value after power on 85 degrees)
papperone (1):
merge with main branch (#648)
-------------------------------------------------
Changes in release mega-20180116 (since mega-20180114)
-------------------------------------------------
Release date: Tue Jan 16 05:00:11 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180113
Edwin Eefting (2):
testsuite: working on generic http/mqtt controller emulatior receiving
fixed custom build path
Gijs Noorlander (1):
[AutoDST] Added Auto DST (Bugfix/v2.0 issue569) (#726)
-------------------------------------------------
Changes in release mega-20180114 (since mega-20180113)
-------------------------------------------------
Release date: Sun Jan 14 05:00:08 CET 2018
s0170071 (1):
preparations for lwip2 (#707)
-------------------------------------------------
Changes in release mega-20180113 (since mega-20180112)
-------------------------------------------------
Release date: Sat Jan 13 05:00:10 CET 2018
Edwin Eefting (2):
ESPEasy v2.0 only supports compiling under arduino core 2.3.0 to prevent issues like #705 when people use Arduino IDE to compile with arduino core 2.4.0
fix version number
-------------------------------------------------
Changes in release mega-20180112 (since mega-20180111)
-------------------------------------------------
Release date: Fri Jan 12 02:05:49 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180111
Edwin Eefting (8):
added http server emulation and domotics http to testsuite
first http domoticz test works
testsuite requirements
fixed releasebot issues with multiple branches
automaticly updated release notes for v2.0-20180112
release bot fixes
dont make same release twice
dont make same release twice
Gijs Noorlander (2):
[Issue 699] Incorrect shown device name (#700)
[v2.0 #470] Do not send invalid values to a controller (#701)
-------------------------------------------------
Changes in release mega-20180111 (since v2.0-20180110)
-------------------------------------------------
Release date: Thu Jan 11 05:00:08 CET 2018
Alexander Schulz (1):
improvement: Configurable number of tasks for "Devices" page (TASKS_P…
BadWolf42 (1):
Dallas Plugin enhanced : no more "delay()" (#488)
Bartłomiej Zimoń (1):
Update _C002.ino (#645)
DaM (1):
[Domoticz HTTP] Compatibility fix for BMP280 (#636)
ESPEasy release bot (5):
created releasebot script
automaticly updated release notes for mega-01022018
automaticly updated release notes for mega-01032018
changed date format of nightly builds
automaticly updated release notes for mega-20180104
Edwin Eefting (22):
keep TASKS_PER_PAGE at default value of 4
fix plugin id (starting with a 0 makes it octal in c++ :( )
fix warnings
fixed bug in oled upstream lib
test fixes
smooth out testing code
esptest stuff
fix travis build errors. disable cpp checking for now
set lcd to NULL by default. #584
fix illegal string manipulations in PLUGIN_WRITE for some plugins. fixes #347 and #460
fix #588. parseTemplate() now only checks enabled taskes for [] macros
testing for ds18b20
updated travis link to reflect v2.0
changed readme to reflect mega branch and automated builds
updates version numbering documentation
changed devicecombobox handling to save a lot of memory on device page. fixes #654 #676 and could be triggered by #683 in some cases.
oops...somehow git did made some changes :(
copied test-stuff from mega to v2.0 to do some testing
analysed some code and added comments
test suite fixes
added frame oled test
working on http mocker for test suite
GHolli (1):
Cosmetics: fixing typos. (#628)
Gijs Noorlander (14):
P028 to support both BME280 and BMP280 to reduce resource usage (#481)
Single function for format to user defined number decimals (#482)
OLED framed improve header footer (#495)
[SSD1306] Feature/oled 1306 library upgrade (#501)
[MH-Z19] Allow for B-version and add filtering (#525)
Support both SSD1306 and SH1106 OLED in OLED_Framed plugin (#509)
[LCD plugin] Added check of LCD object before dereferencing it (#584)
[P039 Thermocouple] Handling negative values and proper error logging (#586)
Reduce iRAM usage for plugins using SoftwareSerial (#631)
[Security] Add IP-based filtering to web interface and http-commands. (#653)
[SDS011] Allow the sensor to sleep to extend sensor lifetime (#668)
[CPPcheck] v2.0 ControllerSettingsStruct some variables not initialized (#692)
Merge/v2.0 dev13 to mega (#695)
[v2.0_kamstrup] Plugin configuration does not load (#697)
Grovkillen (6):
Added categories... (#552)
Changed bin file names to be more descriptive. (#597)
Move "TTP229 keypad" and "Encoder" plugin from "testing" to "normal" (#619)
Updated ESPTOOLS.exe from 0.4.6 to 0.4.12 (#627)
Updated "/pinstates" page: Made the plugin number column display "P001" instead of "1" and "P012" instead of "12".
Update README.md
M0ebiu5 (1):
P022_PCA9685 added change frequency - P038_NeoPixel added RGBW strips (SK6812) (#638)
Michael (2):
WebServer.ino: enhance handle_SDfilelist() (#507)
src/Hardware.ino: make it possible to use GPIO-0 (D3) as Pin_sd_cs (#508)
Sen Haerens (1):
Enhanced system info layout (#624)
SightofSilence (1):
Add System Variable for day, month and year / Fix for "Calculate" function to recognize minus-sign (#485)
SloMusti (1):
implemewnted web activity timer tracker (#462)
Tomasz Torcz (1):
retain MQTT LWT messages (#516)
denisfrench (1):
Set MQTT clientid to %sysname% +/- Settings.Unit (#431) (#436)
fensoft (1):
added #define FEATURE_SD (permit a flash size reduction of ~10k) (#568)
hatzlhoffer (1):
added new display size 128x32 (#545)
krikk (1):
added support for the TSL2591 Sensor based on Adafruit Library (#661)
mvdbro (8):
First preparations for ESP32
ESP32 IRAM/Deepsleep
ESP32 Rules/ADC/PWM
ESP32 fix FreeRAM reporting
ESP32 Enabled OTA
ESP32 fix UDP instability
ESP32 fixed chunked HTTP transfer
Fix #599
papperone (3):
Plugin 073 - 7-segment display plugin TM1637/MAX7219
Update _P073_7DGT.ino (#553)
deleted GPIO notes referring to 75HC595 not supported (#591)
paulv888 (1):
usesID = true (#666)
s0170071 (2):
split IP addrress (#605)
fix chunking (#649)
sakinit (1):
Fix p1 wifi gateway module (#587)
-------------------------------------------------
Changes in release mega-20180104 (since mega-01032018)
-------------------------------------------------
Release date: Thu Jan 4 03:13:01 UTC 2018
ESPEasy release bot (1):
changed date format of nightly builds
-------------------------------------------------
Changes in release mega-01032018 (since mega-01022018)
-------------------------------------------------
Release date: Wed Jan 3 04:00:06 UTC 2018
Edwin Eefting (4):
updated readme to reflect new binary names
updated travis link to reflect v2.0
updated travis link to reflect v2.0
changed readme to reflect mega branch and automated builds
-------------------------------------------------
Changes in release mega-01022018 (since v2.0.0-dev13)
-------------------------------------------------
Release date: Tue Jan 2 23:32:50 UTC 2018
Alexander Schulz (1):
improvement: Configurable number of tasks for "Devices" page (TASKS_P…
BadWolf42 (1):
Dallas Plugin enhanced : no more "delay()" (#488)
Bartłomiej Zimoń (1):
Update _C002.ino (#645)
DaM (1):
[Domoticz HTTP] Compatibility fix for BMP280 (#636)
ESPEasy release bot (1):
created releasebot script
Edwin Eefting (12):
keep TASKS_PER_PAGE at default value of 4
fix plugin id (starting with a 0 makes it octal in c++ :( )
fix warnings
fixed bug in oled upstream lib
test fixes
smooth out testing code
esptest stuff
fix travis build errors. disable cpp checking for now
set lcd to NULL by default. #584
fix illegal string manipulations in PLUGIN_WRITE for some plugins. fixes #347 and #460
fix #588. parseTemplate() now only checks enabled taskes for [] macros
testing for ds18b20
GHolli (1):
Cosmetics: fixing typos. (#628)
Gijs Noorlander (11):
P028 to support both BME280 and BMP280 to reduce resource usage (#481)
Single function for format to user defined number decimals (#482)
OLED framed improve header footer (#495)
[SSD1306] Feature/oled 1306 library upgrade (#501)
[MH-Z19] Allow for B-version and add filtering (#525)
Support both SSD1306 and SH1106 OLED in OLED_Framed plugin (#509)
[LCD plugin] Added check of LCD object before dereferencing it (#584)
[P039 Thermocouple] Handling negative values and proper error logging (#586)
Reduce iRAM usage for plugins using SoftwareSerial (#631)
[Security] Add IP-based filtering to web interface and http-commands. (#653)
[SDS011] Allow the sensor to sleep to extend sensor lifetime (#668)
Grovkillen (5):
Added categories... (#552)
Changed bin file names to be more descriptive. (#597)
Move "TTP229 keypad" and "Encoder" plugin from "testing" to "normal" (#619)
Updated ESPTOOLS.exe from 0.4.6 to 0.4.12 (#627)
Updated "/pinstates" page: Made the plugin number column display "P001" instead of "1" and "P012" instead of "12".
M0ebiu5 (1):
P022_PCA9685 added change frequency - P038_NeoPixel added RGBW strips (SK6812) (#638)
Michael (2):
WebServer.ino: enhance handle_SDfilelist() (#507)
src/Hardware.ino: make it possible to use GPIO-0 (D3) as Pin_sd_cs (#508)
Sen Haerens (1):
Enhanced system info layout (#624)
SightofSilence (1):
Add System Variable for day, month and year / Fix for "Calculate" function to recognize minus-sign (#485)
SloMusti (1):
implemewnted web activity timer tracker (#462)
Tomasz Torcz (1):
retain MQTT LWT messages (#516)
denisfrench (1):
Set MQTT clientid to %sysname% +/- Settings.Unit (#431) (#436)
fensoft (1):
added #define FEATURE_SD (permit a flash size reduction of ~10k) (#568)
hatzlhoffer (1):
added new display size 128x32 (#545)
krikk (1):
added support for the TSL2591 Sensor based on Adafruit Library (#661)
mvdbro (8):
First preparations for ESP32
ESP32 IRAM/Deepsleep
ESP32 Rules/ADC/PWM
ESP32 fix FreeRAM reporting
ESP32 Enabled OTA
ESP32 fix UDP instability
ESP32 fixed chunked HTTP transfer
Fix #599
papperone (3):
Plugin 073 - 7-segment display plugin TM1637/MAX7219
Update _P073_7DGT.ino (#553)
deleted GPIO notes referring to 75HC595 not supported (#591)
paulv888 (1):
usesID = true (#666)
s0170071 (2):
split IP addrress (#605)
fix chunking (#649)
sakinit (1):
Fix p1 wifi gateway module (#587)
-------------------------------------------------
Changes in release v2.0.0-dev13 (since v2.0.0-dev12)
-------------------------------------------------
BIN
View File
Binary file not shown.
+10 -10
View File
@@ -1,16 +1,16 @@
/***************************************************
/***************************************************
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
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
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.
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
@@ -21,26 +21,26 @@ 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("$"); 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);
setThresholds(12, 6);
writeRegister(MPR121_MHDR, 0x01);
writeRegister(MPR121_NHDR, 0x01);
writeRegister(MPR121_NCLR, 0x0E);
+154
View File
@@ -0,0 +1,154 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software< /span>
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Update by K. Townsend (Adafruit Industries) for lighter typedefs, and
* extended sensor support to include color, voltage and current */
#ifndef _ADAFRUIT_SENSOR_H
#define _ADAFRUIT_SENSOR_H
#if ARDUINO >= 100
#include "Arduino.h"
#include "Print.h"
#else
#include "WProgram.h"
#endif
/* Intentionally modeled after sensors.h in the Android API:
* https://github.com/android/platform_hardware_libhardware/blob/master/include/hardware/sensors.h */
/* Constants */
#define SENSORS_GRAVITY_EARTH (9.80665F) /**< Earth's gravity in m/s^2 */
#define SENSORS_GRAVITY_MOON (1.6F) /**< The moon's gravity in m/s^2 */
#define SENSORS_GRAVITY_SUN (275.0F) /**< The sun's gravity in m/s^2 */
#define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH)
#define SENSORS_MAGFIELD_EARTH_MAX (60.0F) /**< Maximum magnetic field on Earth's surface */
#define SENSORS_MAGFIELD_EARTH_MIN (30.0F) /**< Minimum magnetic field on Earth's surface */
#define SENSORS_PRESSURE_SEALEVELHPA (1013.25F) /**< Average sea level pressure is 1013.25 hPa */
#define SENSORS_DPS_TO_RADS (0.017453293F) /**< Degrees/s to rad/s multiplier */
#define SENSORS_GAUSS_TO_MICROTESLA (100) /**< Gauss to micro-Tesla multiplier */
/** Sensor types */
typedef enum
{
SENSOR_TYPE_ACCELEROMETER = (1), /**< Gravity + linear acceleration */
SENSOR_TYPE_MAGNETIC_FIELD = (2),
SENSOR_TYPE_ORIENTATION = (3),
SENSOR_TYPE_GYROSCOPE = (4),
SENSOR_TYPE_LIGHT = (5),
SENSOR_TYPE_PRESSURE = (6),
SENSOR_TYPE_PROXIMITY = (8),
SENSOR_TYPE_GRAVITY = (9),
SENSOR_TYPE_LINEAR_ACCELERATION = (10), /**< Acceleration not including gravity */
SENSOR_TYPE_ROTATION_VECTOR = (11),
SENSOR_TYPE_RELATIVE_HUMIDITY = (12),
SENSOR_TYPE_AMBIENT_TEMPERATURE = (13),
SENSOR_TYPE_VOLTAGE = (15),
SENSOR_TYPE_CURRENT = (16),
SENSOR_TYPE_COLOR = (17)
} sensors_type_t;
/** struct sensors_vec_s is used to return a vector in a common format. */
typedef struct {
union {
float v[3];
struct {
float x;
float y;
float z;
};
/* Orientation sensors */
struct {
float roll; /**< Rotation around the longitudinal axis (the plane body, 'X axis'). Roll is positive and increasing when moving downward. -90°<=roll<=90° */
float pitch; /**< Rotation around the lateral axis (the wing span, 'Y axis'). Pitch is positive and increasing when moving upwards. -180°<=pitch<=180°) */
float heading; /**< Angle between the longitudinal axis (the plane body) and magnetic north, measured clockwise when viewing from the top of the device. 0-359° */
};
};
int8_t status;
uint8_t reserved[3];
} sensors_vec_t;
/** struct sensors_color_s is used to return color data in a common format. */
typedef struct {
union {
float c[3];
/* RGB color space */
struct {
float r; /**< Red component */
float g; /**< Green component */
float b; /**< Blue component */
};
};
uint32_t rgba; /**< 24-bit RGBA value */
} sensors_color_t;
/* Sensor event (36 bytes) */
/** struct sensor_event_s is used to provide a single sensor event in a common format. */
typedef struct
{
int32_t version; /**< must be sizeof(struct sensors_event_t) */
int32_t sensor_id; /**< unique sensor identifier */
int32_t type; /**< sensor type */
int32_t reserved0; /**< reserved */
int32_t timestamp; /**< time is in milliseconds */
union
{
float data[4];
sensors_vec_t acceleration; /**< acceleration values are in meter per second per second (m/s^2) */
sensors_vec_t magnetic; /**< magnetic vector values are in micro-Tesla (uT) */
sensors_vec_t orientation; /**< orientation values are in degrees */
sensors_vec_t gyro; /**< gyroscope values are in rad/s */
float temperature; /**< temperature is in degrees centigrade (Celsius) */
float distance; /**< distance in centimeters */
float light; /**< light in SI lux units */
float pressure; /**< pressure in hectopascal (hPa) */
float relative_humidity; /**< relative humidity in percent */
float current; /**< current in milliamps (mA) */
float voltage; /**< voltage in volts (V) */
sensors_color_t color; /**< color in RGB component values */
};
} sensors_event_t;
/* Sensor details (40 bytes) */
/** struct sensor_s is used to describe basic information about a specific sensor. */
typedef struct
{
char name[12]; /**< sensor name */
int32_t version; /**< version of the hardware + driver */
int32_t sensor_id; /**< unique sensor identifier */
int32_t type; /**< this sensor's type (ex. SENSOR_TYPE_LIGHT) */
float max_value; /**< maximum value of this sensor's value in SI units */
float min_value; /**< minimum value of this sensor's value in SI units */
float resolution; /**< smallest difference between two values reported by this sensor */
int32_t min_delay; /**< min delay in microseconds between events. zero = not a constant rate */
} sensor_t;
class Adafruit_Sensor {
public:
// Constructor(s)
Adafruit_Sensor() {}
virtual ~Adafruit_Sensor() {}
// These must be defined by the subclass
virtual void enableAutoRange(bool enabled) {};
virtual bool getEvent(sensors_event_t*) = 0;
virtual void getSensor(sensor_t*) = 0;
private:
bool _autoRange;
};
#endif
+221
View File
@@ -0,0 +1,221 @@
# Adafruit Unified Sensor Driver #
Many small embedded systems exist to collect data from sensors, analyse the data, and either take an appropriate action or send that sensor data to another system for processing.
One of the many challenges of embedded systems design is the fact that parts you used today may be out of production tomorrow, or system requirements may change and you may need to choose a different sensor down the road.
Creating new drivers is a relatively easy task, but integrating them into existing systems is both error prone and time consuming since sensors rarely use the exact same units of measurement.
By reducing all data to a single **sensors\_event\_t** 'type' and settling on specific, **standardised SI units** for each sensor family the same sensor types return values that are comparable with any other similar sensor. This enables you to switch sensor models with very little impact on the rest of the system, which can help mitigate some of the risks and problems of sensor availability and code reuse.
The unified sensor abstraction layer is also useful for data-logging and data-transmission since you only have one well-known type to log or transmit over the air or wire.
## Unified Sensor Drivers ##
The following drivers are based on the Adafruit Unified Sensor Driver:
**Accelerometers**
- [Adafruit\_ADXL345](https://github.com/adafruit/Adafruit_ADXL345)
- [Adafruit\_LSM303DLHC](https://github.com/adafruit/Adafruit_LSM303DLHC)
- [Adafruit\_MMA8451\_Library](https://github.com/adafruit/Adafruit_MMA8451_Library)
**Gyroscope**
- [Adafruit\_L3GD20\_U](https://github.com/adafruit/Adafruit_L3GD20_U)
**Light**
- [Adafruit\_TSL2561](https://github.com/adafruit/Adafruit_TSL2561)
- [Adafruit\_TSL2591\_Library](https://github.com/adafruit/Adafruit_TSL2591_Library)
**Magnetometers**
- [Adafruit\_LSM303DLHC](https://github.com/adafruit/Adafruit_LSM303DLHC)
- [Adafruit\_HMC5883\_Unified](https://github.com/adafruit/Adafruit_HMC5883_Unified)
**Barometric Pressure**
- [Adafruit\_BMP085\_Unified](https://github.com/adafruit/Adafruit_BMP085_Unified)
- [Adafruit\_BMP183\_Unified\_Library](https://github.com/adafruit/Adafruit_BMP183_Unified_Library)
**Humidity & Temperature**
- [DHT-sensor-library](https://github.com/adafruit/DHT-sensor-library)
**Orientation**
- [Adafruit_BNO055](https://github.com/adafruit/Adafruit_BNO055)
## How Does it Work? ##
Any driver that supports the Adafruit unified sensor abstraction layer will implement the Adafruit\_Sensor base class. There are two main typedefs and one enum defined in Adafruit_Sensor.h that are used to 'abstract' away the sensor details and values:
**Sensor Types (sensors\_type\_t)**
These pre-defined sensor types are used to properly handle the two related typedefs below, and allows us determine what types of units the sensor uses, etc.
```
/** Sensor types */
typedef enum
{
SENSOR_TYPE_ACCELEROMETER = (1),
SENSOR_TYPE_MAGNETIC_FIELD = (2),
SENSOR_TYPE_ORIENTATION = (3),
SENSOR_TYPE_GYROSCOPE = (4),
SENSOR_TYPE_LIGHT = (5),
SENSOR_TYPE_PRESSURE = (6),
SENSOR_TYPE_PROXIMITY = (8),
SENSOR_TYPE_GRAVITY = (9),
SENSOR_TYPE_LINEAR_ACCELERATION = (10),
SENSOR_TYPE_ROTATION_VECTOR = (11),
SENSOR_TYPE_RELATIVE_HUMIDITY = (12),
SENSOR_TYPE_AMBIENT_TEMPERATURE = (13),
SENSOR_TYPE_VOLTAGE = (15),
SENSOR_TYPE_CURRENT = (16),
SENSOR_TYPE_COLOR = (17)
} sensors_type_t;
```
**Sensor Details (sensor\_t)**
This typedef describes the specific capabilities of this sensor, and allows us to know what sensor we are using beneath the abstraction layer.
```
/* Sensor details (40 bytes) */
/** struct sensor_s is used to describe basic information about a specific sensor. */
typedef struct
{
char name[12];
int32_t version;
int32_t sensor_id;
int32_t type;
float max_value;
float min_value;
float resolution;
int32_t min_delay;
} sensor_t;
```
The individual fields are intended to be used as follows:
- **name**: The sensor name or ID, up to a maximum of twelve characters (ex. "MPL115A2")
- **version**: The version of the sensor HW and the driver to allow us to differentiate versions of the board or driver
- **sensor\_id**: A unique sensor identifier that is used to differentiate this specific sensor instance from any others that are present on the system or in the sensor network
- **type**: The sensor type, based on **sensors\_type\_t** in sensors.h
- **max\_value**: The maximum value that this sensor can return (in the appropriate SI unit)
- **min\_value**: The minimum value that this sensor can return (in the appropriate SI unit)
- **resolution**: The smallest difference between two values that this sensor can report (in the appropriate SI unit)
- **min\_delay**: The minimum delay in microseconds between two sensor events, or '0' if there is no constant sensor rate
**Sensor Data/Events (sensors\_event\_t)**
This typedef is used to return sensor data from any sensor supported by the abstraction layer, using standard SI units and scales.
```
/* Sensor event (36 bytes) */
/** struct sensor_event_s is used to provide a single sensor event in a common format. */
typedef struct
{
int32_t version;
int32_t sensor_id;
int32_t type;
int32_t reserved0;
int32_t timestamp;
union
{
float data[4];
sensors_vec_t acceleration;
sensors_vec_t magnetic;
sensors_vec_t orientation;
sensors_vec_t gyro;
float temperature;
float distance;
float light;
float pressure;
float relative_humidity;
float current;
float voltage;
sensors_color_t color;
};
} sensors_event_t;
```
It includes the following fields:
- **version**: Contain 'sizeof(sensors\_event\_t)' to identify which version of the API we're using in case this changes in the future
- **sensor\_id**: A unique sensor identifier that is used to differentiate this specific sensor instance from any others that are present on the system or in the sensor network (must match the sensor\_id value in the corresponding sensor\_t enum above!)
- **type**: the sensor type, based on **sensors\_type\_t** in sensors.h
- **timestamp**: time in milliseconds when the sensor value was read
- **data[4]**: An array of four 32-bit values that allows us to encapsulate any type of sensor data via a simple union (further described below)
**Required Functions**
In addition to the two standard types and the sensor type enum, all drivers based on Adafruit_Sensor must also implement the following two functions:
```
bool getEvent(sensors_event_t*);
```
Calling this function will populate the supplied sensors\_event\_t reference with the latest available sensor data. You should call this function as often as you want to update your data.
```
void getSensor(sensor_t*);
```
Calling this function will provide some basic information about the sensor (the sensor name, driver version, min and max values, etc.
**Standardised SI values for sensors\_event\_t**
A key part of the abstraction layer is the standardisation of values on SI units of a particular scale, which is accomplished via the data[4] union in sensors\_event\_t above. This 16 byte union includes fields for each main sensor type, and uses the following SI units and scales:
- **acceleration**: values are in **meter per second per second** (m/s^2)
- **magnetic**: values are in **micro-Tesla** (uT)
- **orientation**: values are in **degrees**
- **gyro**: values are in **rad/s**
- **temperature**: values in **degrees centigrade** (Celsius)
- **distance**: values are in **centimeters**
- **light**: values are in **SI lux** units
- **pressure**: values are in **hectopascal** (hPa)
- **relative\_humidity**: values are in **percent**
- **current**: values are in **milliamps** (mA)
- **voltage**: values are in **volts** (V)
- **color**: values are in 0..1.0 RGB channel luminosity and 32-bit RGBA format
## The Unified Driver Abstraction Layer in Practice ##
Using the unified sensor abstraction layer is relatively easy once a compliant driver has been created.
Every compliant sensor can now be read using a single, well-known 'type' (sensors\_event\_t), and there is a standardised way of interrogating a sensor about its specific capabilities (via sensor\_t).
An example of reading the [TSL2561](https://github.com/adafruit/Adafruit_TSL2561) light sensor can be seen below:
```
Adafruit_TSL2561 tsl = Adafruit_TSL2561(TSL2561_ADDR_FLOAT, 12345);
...
/* Get a new sensor event */
sensors_event_t event;
tsl.getEvent(&event);
/* Display the results (light is measured in lux) */
if (event.light)
{
Serial.print(event.light); Serial.println(" lux");
}
else
{
/* If event.light = 0 lux the sensor is probably saturated
and no reliable data could be generated! */
Serial.println("Sensor overload");
}
```
Similarly, we can get the basic technical capabilities of this sensor with the following code:
```
sensor_t sensor;
sensor_t sensor;
tsl.getSensor(&sensor);
/* Display the sensor details */
Serial.println("------------------------------------");
Serial.print ("Sensor: "); Serial.println(sensor.name);
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" lux");
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" lux");
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" lux");
Serial.println("------------------------------------");
Serial.println("");
```
+9
View File
@@ -0,0 +1,9 @@
name=Adafruit Unified Sensor
version=1.0.2
author=Adafruit <info@adafruit.com>
maintainer=Adafruit <info@adafruit.com>
sentence=Required for all Adafruit Unified Sensor based libraries.
paragraph=A unified sensor abstraction layer used by many Adafruit sensor libraries.
category=Sensors
url=https://github.com/adafruit/Adafruit_Sensor
architectures=*
+46
View File
@@ -0,0 +1,46 @@
Thank you for opening an issue on an Adafruit Arduino library repository. To
improve the speed of resolution please review the following guidelines and
common troubleshooting steps below before creating the issue:
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
something isn't working as expected. In many cases the problem is a common issue
that you will more quickly receive help from the forum community. GitHub issues
are meant for known defects in the code. If you don't know if there is a defect
in the code then start with troubleshooting on the forum first.
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
check all of the steps and commands to run have been followed. Consult the
forum if you're unsure or have questions about steps in a guide/tutorial.
- **For Arduino projects check these very common issues to ensure they don't apply**:
- For uploading sketches or communicating with the board make sure you're using
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
very hard to tell the difference between a data and charge cable! Try using the
cable with other devices or swapping to another cable to confirm it is not
the problem.
- **Be sure you are supplying adequate power to the board.** Check the specs of
your board and plug in an external power supply. In many cases just
plugging a board into your computer is not enough to power it and other
peripherals.
- **Double check all soldering joints and connections.** Flakey connections
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
- **Ensure you are using an official Arduino or Adafruit board.** We can't
guarantee a clone board will have the same functionality and work as expected
with this code and don't support them.
If you're sure this issue is a defect in the code and checked the steps above
please fill in the following fields to provide enough troubleshooting information.
You may delete the guideline and text above to just leave the following details:
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
VERSION HERE**
- List the steps to reproduce the problem below (if possible attach a sketch or
copy the sketch code in too): **LIST REPRO STEPS BELOW**
+26
View File
@@ -0,0 +1,26 @@
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
Before you open the request please review the following guidelines and tips to
help it be more easily integrated:
- **Describe the scope of your change--i.e. what the change does and what parts
of the code were modified.** This will help us understand any risks of integrating
the code.
- **Describe any known limitations with your change.** For example if the change
doesn't apply to a supported platform of the library please mention it.
- **Please run any tests or examples that can exercise your modified code.** We
strive to not break users of the code and running tests/examples helps with this
process.
Thank you again for contributing! We will try to test and integrate the change
as soon as we can, but be aware we have many GitHub repositories to manage and
can't immediately respond to every request. There is no need to bump or check in
on a pull request (it will clutter the discussion of the request).
Also don't be worried if the request is closed or not integrated--sometimes the
priorities of Adafruit's GitHub code (education, ease of use) might not match the
priorities of the pull request. Don't fret, the open source community thrives on
forks and GitHub makes it easy to keep your changes in a forked repo.
After reviewing the guidelines above you can delete this text from the pull request.
+504
View File
@@ -0,0 +1,504 @@
/**************************************************************************/
/*!
@file Adafruit_TSL2591.cpp
@author KT0WN (adafruit.com)
This is a library for the Adafruit TSL2591 breakout board
This library works with the Adafruit TSL2591 breakout
----> https://www.adafruit.com/products/1980
Check out the links above for our tutorials and wiring diagrams
These chips use I2C to communicate
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2014 Adafruit Industries
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**************************************************************************/
#if defined(ESP8266) || defined(ESP32)
#include <pgmspace.h>
#else
#include <avr/pgmspace.h>
#endif
#if defined(__AVR__)
#include <util/delay.h>
#endif
#include <stdlib.h>
#include "Adafruit_TSL2591.h"
Adafruit_TSL2591::Adafruit_TSL2591(int32_t sensorID)
{
_initialized = false;
_integration = TSL2591_INTEGRATIONTIME_100MS;
_gain = TSL2591_GAIN_MED;
_sensorID = sensorID;
// we cant do wire initialization till later, because we havent loaded Wire yet
}
boolean Adafruit_TSL2591::begin(void)
{
Wire.begin();
/*
for (uint8_t i=0; i<0x20; i++)
{
uint8_t id = read8(0x12);
Serial.print("$"); Serial.print(i, HEX);
Serial.print(" = 0x"); Serial.println(read8(i), HEX);
}
*/
uint8_t id = read8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_DEVICE_ID);
if (id == 0x50 )
{
// Serial.println("Found Adafruit_TSL2591");
}
else
{
return false;
}
_initialized = true;
// Set default integration time and gain
setTiming(_integration);
setGain(_gain);
// Note: by default, the device is in power down mode on bootup
disable();
return true;
}
void Adafruit_TSL2591::enable(void)
{
if (!_initialized)
{
if (!begin())
{
return;
}
}
// Enable the device by setting the control bit to 0x01
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWERON | TSL2591_ENABLE_AEN | TSL2591_ENABLE_AIEN | TSL2591_ENABLE_NPIEN);
}
void Adafruit_TSL2591::disable(void)
{
if (!_initialized)
{
if (!begin())
{
return;
}
}
// Disable the device by setting the control bit to 0x00
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWEROFF);
}
void Adafruit_TSL2591::setGain(tsl2591Gain_t gain)
{
if (!_initialized)
{
if (!begin())
{
return;
}
}
enable();
_gain = gain;
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain);
disable();
}
tsl2591Gain_t Adafruit_TSL2591::getGain()
{
return _gain;
}
void Adafruit_TSL2591::setTiming(tsl2591IntegrationTime_t integration)
{
if (!_initialized)
{
if (!begin())
{
return;
}
}
enable();
_integration = integration;
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain);
disable();
}
tsl2591IntegrationTime_t Adafruit_TSL2591::getTiming()
{
return _integration;
}
float Adafruit_TSL2591::calculateLuxf(uint16_t ch0, uint16_t ch1)
{
float atime, again;
float cpl, lux1, lux2, lux;
uint32_t chan0, chan1;
// Check for overflow conditions first
if ((ch0 == 0xFFFF) | (ch1 == 0xFFFF))
{
// Signal an overflow
return 0;
}
// Note: This algorithm is based on preliminary coefficients
// provided by AMS and may need to be updated in the future
switch (_integration)
{
case TSL2591_INTEGRATIONTIME_100MS :
atime = 100.0F;
break;
case TSL2591_INTEGRATIONTIME_200MS :
atime = 200.0F;
break;
case TSL2591_INTEGRATIONTIME_300MS :
atime = 300.0F;
break;
case TSL2591_INTEGRATIONTIME_400MS :
atime = 400.0F;
break;
case TSL2591_INTEGRATIONTIME_500MS :
atime = 500.0F;
break;
case TSL2591_INTEGRATIONTIME_600MS :
atime = 600.0F;
break;
default: // 100ms
atime = 100.0F;
break;
}
switch (_gain)
{
case TSL2591_GAIN_LOW :
again = 1.0F;
break;
case TSL2591_GAIN_MED :
again = 25.0F;
break;
case TSL2591_GAIN_HIGH :
again = 428.0F;
break;
case TSL2591_GAIN_MAX :
again = 9876.0F;
break;
default:
again = 1.0F;
break;
}
// cpl = (ATIME * AGAIN) / DF
cpl = (atime * again) / TSL2591_LUX_DF;
lux1 = (((float) ch0 - (float) ch1)) * (1.0F - ((float) ch1 / (float) ch0)) / cpl;//( (float)ch0 - (TSL2591_LUX_COEFB * (float)ch1) ) / cpl;
lux2 = ((TSL2591_LUX_COEFC * (float) ch0) - (TSL2591_LUX_COEFD * (float) ch1)) / cpl;
lux = lux1 > lux2 ? lux1 : lux2;
// Alternate lux calculation
//lux = ( (float)ch0 - ( 1.7F * (float)ch1 ) ) / cpl;
// Signal I2C had no errors
return lux;
}
uint32_t Adafruit_TSL2591::calculateLux(uint16_t ch0, uint16_t ch1)
{
return (uint32_t) calculateLuxf(ch0, ch1);
}
uint32_t Adafruit_TSL2591::getFullLuminosity (void)
{
if (!_initialized)
{
if (!begin())
{
return 0;
}
}
// Enable the device
enable();
// Wait x ms for ADC to complete
for (uint8_t d=0; d<=_integration; d++)
{
delay(120);
}
uint32_t x;
uint16_t y;
y |= read16(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_LOW);
x = read16(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_LOW);
x <<= 16;
x |= y;
disable();
return x;
}
uint16_t Adafruit_TSL2591::getLuminosity (uint8_t channel)
{
uint32_t x = getFullLuminosity();
if (channel == TSL2591_FULLSPECTRUM)
{
// Reads two byte value from channel 0 (visible + infrared)
return (x & 0xFFFF);
}
else if (channel == TSL2591_INFRARED)
{
// Reads two byte value from channel 1 (infrared)
return (x >> 16);
}
else if (channel == TSL2591_VISIBLE)
{
// Reads all and subtracts out just the visible!
return ( (x & 0xFFFF) - (x >> 16));
}
// unknown channel!
return 0;
}
void Adafruit_TSL2591::registerInterrupt(uint16_t lowerThreshold, uint16_t upperThreshold)
{
if (!_initialized)
{
if (!begin())
{
return;
}
}
enable();
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_NPAILTL, lowerThreshold);
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_NPAILTH, lowerThreshold >> 8);
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_NPAIHTL, upperThreshold);
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_NPAIHTH, upperThreshold >> 8);
disable();
}
void Adafruit_TSL2591::registerInterrupt(uint16_t lowerThreshold, uint16_t upperThreshold, tsl2591Persist_t persist)
{
if (!_initialized)
{
if (!begin())
{
return;
}
}
enable();
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_PERSIST_FILTER, persist);
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_AILTL, lowerThreshold);
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_AILTH, lowerThreshold >> 8);
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_AIHTL, upperThreshold);
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_AIHTH, upperThreshold >> 8);
disable();
}
void Adafruit_TSL2591::clearInterrupt()
{
if (!_initialized)
{
if (!begin())
{
return;
}
}
enable();
write8(TSL2591_CLEAR_INT);
disable();
}
uint8_t Adafruit_TSL2591::getStatus()
{
if (!_initialized)
{
if (!begin())
{
return 0;
}
}
// Enable the device
enable();
uint8_t x;
x = read8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_DEVICE_STATUS);
disable();
return x;
}
uint8_t Adafruit_TSL2591::read8(uint8_t reg)
{
uint8_t x;
Wire.beginTransmission(TSL2591_ADDR);
#if ARDUINO >= 100
Wire.write(reg);
#else
Wire.send(reg);
#endif
Wire.endTransmission();
Wire.requestFrom(TSL2591_ADDR, 1);
#if ARDUINO >= 100
x = Wire.read();
#else
x = Wire.receive();
#endif
// while (! Wire.available());
// return Wire.read();
return x;
}
uint16_t Adafruit_TSL2591::read16(uint8_t reg)
{
uint16_t x;
uint16_t t;
Wire.beginTransmission(TSL2591_ADDR);
#if ARDUINO >= 100
Wire.write(reg);
#else
Wire.send(reg);
#endif
Wire.endTransmission();
Wire.requestFrom(TSL2591_ADDR, 2);
#if ARDUINO >= 100
t = Wire.read();
x = Wire.read();
#else
t = Wire.receive();
x = Wire.receive();
#endif
x <<= 8;
x |= t;
return x;
}
void Adafruit_TSL2591::write8 (uint8_t reg, uint8_t value)
{
Wire.beginTransmission(TSL2591_ADDR);
#if ARDUINO >= 100
Wire.write(reg);
Wire.write(value);
#else
Wire.send(reg);
Wire.send(value);
#endif
Wire.endTransmission();
}
void Adafruit_TSL2591::write8 (uint8_t reg)
{
Wire.beginTransmission(TSL2591_ADDR);
#if ARDUINO >= 100
Wire.write(reg);
#else
Wire.send(reg);
#endif
Wire.endTransmission();
}
/**************************************************************************/
/*!
@brief Gets the most recent sensor event
*/
/**************************************************************************/
bool Adafruit_TSL2591::getEvent(sensors_event_t *event)
{
uint16_t ir, full;
uint32_t lum = getFullLuminosity();
/* Early silicon seems to have issues when there is a sudden jump in */
/* light levels. :( To work around this for now sample the sensor 2x */
lum = getFullLuminosity();
ir = lum >> 16;
full = lum & 0xFFFF;
/* Clear the event */
memset(event, 0, sizeof(sensors_event_t));
event->version = sizeof(sensors_event_t);
event->sensor_id = _sensorID;
event->type = SENSOR_TYPE_LIGHT;
event->timestamp = millis();
/* Calculate the actual lux value */
/* 0 = sensor overflow (too much light) */
event->light = calculateLux(full, ir);
return true;
}
/**************************************************************************/
/*!
@brief Gets the sensor_t data
*/
/**************************************************************************/
void Adafruit_TSL2591::getSensor(sensor_t *sensor)
{
/* Clear the sensor_t object */
memset(sensor, 0, sizeof(sensor_t));
/* Insert the sensor name in the fixed length char array */
strncpy (sensor->name, "TSL2591", sizeof(sensor->name) - 1);
sensor->name[sizeof(sensor->name)- 1] = 0;
sensor->version = 1;
sensor->sensor_id = _sensorID;
sensor->type = SENSOR_TYPE_LIGHT;
sensor->min_delay = 0;
sensor->max_value = 88000.0;
sensor->min_value = 0.0;
sensor->resolution = 1.0;
}
+187
View File
@@ -0,0 +1,187 @@
/**************************************************************************/
/*!
@file Adafruit_TSL2591.h
@author KT0WN (adafruit.com)
This is a library for the Adafruit TSL2591 breakout board
This library works with the Adafruit TSL2591 breakout
----> https://www.adafruit.com/products/1980
Check out the links above for our tutorials and wiring diagrams
These chips use I2C to communicate
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2014 Adafruit Industries
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**************************************************************************/
#ifndef _TSL2591_H_
#define _TSL2591_H_
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include <Adafruit_Sensor.h>
#include <Wire.h>
#define TSL2591_VISIBLE (2) // channel 0 - channel 1
#define TSL2591_INFRARED (1) // channel 1
#define TSL2591_FULLSPECTRUM (0) // channel 0
#define TSL2591_ADDR (0x29)
#define TSL2591_READBIT (0x01)
#define TSL2591_COMMAND_BIT (0xA0) // 1010 0000: bits 7 and 5 for 'command normal'
#define TSL2591_CLEAR_INT (0xE7)
#define TSL2591_TEST_INT (0xE4)
#define TSL2591_WORD_BIT (0x20) // 1 = read/write word (rather than byte)
#define TSL2591_BLOCK_BIT (0x10) // 1 = using block read/write
#define TSL2591_ENABLE_POWEROFF (0x00)
#define TSL2591_ENABLE_POWERON (0x01)
#define TSL2591_ENABLE_AEN (0x02) // ALS Enable. This field activates ALS function. Writing a one activates the ALS. Writing a zero disables the ALS.
#define TSL2591_ENABLE_AIEN (0x10) // ALS Interrupt Enable. When asserted permits ALS interrupts to be generated, subject to the persist filter.
#define TSL2591_ENABLE_NPIEN (0x80) // No Persist Interrupt Enable. When asserted NP Threshold conditions will generate an interrupt, bypassing the persist filter
#define TSL2591_LUX_DF (408.0F)
#define TSL2591_LUX_COEFB (1.64F) // CH0 coefficient
#define TSL2591_LUX_COEFC (0.59F) // CH1 coefficient A
#define TSL2591_LUX_COEFD (0.86F) // CH2 coefficient B
enum
{
TSL2591_REGISTER_ENABLE = 0x00,
TSL2591_REGISTER_CONTROL = 0x01,
TSL2591_REGISTER_THRESHOLD_AILTL = 0x04, // ALS low threshold lower byte
TSL2591_REGISTER_THRESHOLD_AILTH = 0x05, // ALS low threshold upper byte
TSL2591_REGISTER_THRESHOLD_AIHTL = 0x06, // ALS high threshold lower byte
TSL2591_REGISTER_THRESHOLD_AIHTH = 0x07, // ALS high threshold upper byte
TSL2591_REGISTER_THRESHOLD_NPAILTL = 0x08, // No Persist ALS low threshold lower byte
TSL2591_REGISTER_THRESHOLD_NPAILTH = 0x09, // etc
TSL2591_REGISTER_THRESHOLD_NPAIHTL = 0x0A,
TSL2591_REGISTER_THRESHOLD_NPAIHTH = 0x0B,
TSL2591_REGISTER_PERSIST_FILTER = 0x0C,
TSL2591_REGISTER_PACKAGE_PID = 0x11,
TSL2591_REGISTER_DEVICE_ID = 0x12,
TSL2591_REGISTER_DEVICE_STATUS = 0x13,
TSL2591_REGISTER_CHAN0_LOW = 0x14,
TSL2591_REGISTER_CHAN0_HIGH = 0x15,
TSL2591_REGISTER_CHAN1_LOW = 0x16,
TSL2591_REGISTER_CHAN1_HIGH = 0x17
};
typedef enum
{
TSL2591_INTEGRATIONTIME_100MS = 0x00,
TSL2591_INTEGRATIONTIME_200MS = 0x01,
TSL2591_INTEGRATIONTIME_300MS = 0x02,
TSL2591_INTEGRATIONTIME_400MS = 0x03,
TSL2591_INTEGRATIONTIME_500MS = 0x04,
TSL2591_INTEGRATIONTIME_600MS = 0x05,
}
tsl2591IntegrationTime_t;
typedef enum
{
// bit 7:4: 0
TSL2591_PERSIST_EVERY = 0x00, // Every ALS cycle generates an interrupt
TSL2591_PERSIST_ANY = 0x01, // Any value outside of threshold range
TSL2591_PERSIST_2 = 0x02, // 2 consecutive values out of range
TSL2591_PERSIST_3 = 0x03, // 3 consecutive values out of range
TSL2591_PERSIST_5 = 0x04, // 5 consecutive values out of range
TSL2591_PERSIST_10 = 0x05, // 10 consecutive values out of range
TSL2591_PERSIST_15 = 0x06, // 15 consecutive values out of range
TSL2591_PERSIST_20 = 0x07, // 20 consecutive values out of range
TSL2591_PERSIST_25 = 0x08, // 25 consecutive values out of range
TSL2591_PERSIST_30 = 0x09, // 30 consecutive values out of range
TSL2591_PERSIST_35 = 0x0A, // 35 consecutive values out of range
TSL2591_PERSIST_40 = 0x0B, // 40 consecutive values out of range
TSL2591_PERSIST_45 = 0x0C, // 45 consecutive values out of range
TSL2591_PERSIST_50 = 0x0D, // 50 consecutive values out of range
TSL2591_PERSIST_55 = 0x0E, // 55 consecutive values out of range
TSL2591_PERSIST_60 = 0x0F, // 60 consecutive values out of range
}
tsl2591Persist_t;
typedef enum
{
TSL2591_GAIN_LOW = 0x00, // low gain (1x)
TSL2591_GAIN_MED = 0x10, // medium gain (25x)
TSL2591_GAIN_HIGH = 0x20, // medium gain (428x)
TSL2591_GAIN_MAX = 0x30, // max gain (9876x)
}
tsl2591Gain_t;
class Adafruit_TSL2591 : public Adafruit_Sensor
{
public:
Adafruit_TSL2591(int32_t sensorID = -1);
boolean begin ( void );
void enable ( void );
void disable ( void );
void write8 ( uint8_t r);
void write8 ( uint8_t r, uint8_t v );
uint16_t read16 ( uint8_t reg );
uint8_t read8 ( uint8_t reg );
uint32_t calculateLux ( uint16_t ch0, uint16_t ch1 );
float calculateLuxf ( uint16_t ch0, uint16_t ch1 );
void setGain ( tsl2591Gain_t gain );
void setTiming ( tsl2591IntegrationTime_t integration );
uint16_t getLuminosity (uint8_t channel );
uint32_t getFullLuminosity ( );
tsl2591IntegrationTime_t getTiming();
tsl2591Gain_t getGain();
// Interrupt
void clearInterrupt(void);
void registerInterrupt(uint16_t lowerThreshold, uint16_t upperThreshold);
void registerInterrupt(uint16_t lowerThreshold, uint16_t upperThreshold, tsl2591Persist_t persist);
uint8_t getStatus();
/* Unified Sensor API Functions */
bool getEvent ( sensors_event_t* );
void getSensor ( sensor_t* );
private:
tsl2591IntegrationTime_t _integration;
tsl2591Gain_t _gain;
int32_t _sensorID;
boolean _initialized;
};
#endif
+9
View File
@@ -0,0 +1,9 @@
This is an Arduino library for the TSL2591 digital luminosity (light) sensors.
Pick one up at http://www.adafruit.com/products/1980
To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_TSL2591. Check that the Adafruit_TSL2591 folder contains Adafruit_TSL2591.cpp and Adafruit_TSL2591.h
Place the Adafruit_TSL2591 library folder your <arduinosketchfolder>/libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE.
You'll also need the Adafruit_Sensor library from https://github.com/adafruit/Adafruit_Sensor
@@ -0,0 +1,200 @@
/* TSL2591 Digital Light Sensor */
/* Dynamic Range: 600M:1 */
/* Maximum Lux: 88K */
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h"
// Example for demonstrating the TSL2591 library - public domain!
// connect SCL to analog 5
// connect SDA to analog 4
// connect Vin to 3.3-5V DC
// connect GROUND to common ground
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)
/**************************************************************************/
/*
Displays some basic information on this sensor from the unified
sensor API sensor_t type (see Adafruit_Sensor for more information)
*/
/**************************************************************************/
void displaySensorDetails(void)
{
sensor_t sensor;
tsl.getSensor(&sensor);
Serial.println(F("------------------------------------"));
Serial.print (F("Sensor: ")); Serial.println(sensor.name);
Serial.print (F("Driver Ver: ")); Serial.println(sensor.version);
Serial.print (F("Unique ID: ")); Serial.println(sensor.sensor_id);
Serial.print (F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F(" lux"));
Serial.print (F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F(" lux"));
Serial.print (F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F(" lux"));
Serial.println(F("------------------------------------"));
Serial.println(F(""));
delay(500);
}
/**************************************************************************/
/*
Configures the gain and integration time for the TSL2591
*/
/**************************************************************************/
void configureSensor(void)
{
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
//tsl.setGain(TSL2591_GAIN_LOW); // 1x gain (bright light)
tsl.setGain(TSL2591_GAIN_MED); // 25x gain
// tsl.setGain(TSL2591_GAIN_HIGH); // 428x gain
// Changing the integration time gives you a longer time over which to sense light
// longer timelines are slower, but are good in very low light situtations!
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); // shortest integration time (bright light)
// tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); // longest integration time (dim light)
/* Display the gain and integration time for reference sake */
Serial.println(F("------------------------------------"));
Serial.print (F("Gain: "));
tsl2591Gain_t gain = tsl.getGain();
switch(gain)
{
case TSL2591_GAIN_LOW:
Serial.println(F("1x (Low)"));
break;
case TSL2591_GAIN_MED:
Serial.println(F("25x (Medium)"));
break;
case TSL2591_GAIN_HIGH:
Serial.println(F("428x (High)"));
break;
case TSL2591_GAIN_MAX:
Serial.println(F("9876x (Max)"));
break;
}
Serial.print (F("Timing: "));
Serial.print((tsl.getTiming() + 1) * 100, DEC);
Serial.println(F(" ms"));
Serial.println(F("------------------------------------"));
Serial.println(F(""));
}
/**************************************************************************/
/*
Program entry point for the Arduino sketch
*/
/**************************************************************************/
void setup(void)
{
Serial.begin(9600);
Serial.println(F("Starting Adafruit TSL2591 Test!"));
if (tsl.begin())
{
Serial.println(F("Found a TSL2591 sensor"));
}
else
{
Serial.println(F("No sensor found ... check your wiring?"));
while (1);
}
/* Display some basic information on this sensor */
displaySensorDetails();
/* Configure the sensor */
configureSensor();
// Now we're ready to get readings ... move on to loop()!
}
/**************************************************************************/
/*
Shows how to perform a basic read on visible, full spectrum or
infrared light (returns raw 16-bit ADC values)
*/
/**************************************************************************/
void simpleRead(void)
{
// Simple data read example. Just read the infrared, fullspecrtrum diode
// or 'visible' (difference between the two) channels.
// This can take 100-600 milliseconds! Uncomment whichever of the following you want to read
uint16_t x = tsl.getLuminosity(TSL2591_VISIBLE);
//uint16_t x = tsl.getLuminosity(TSL2591_FULLSPECTRUM);
//uint16_t x = tsl.getLuminosity(TSL2591_INFRARED);
Serial.print(F("[ ")); Serial.print(millis()); Serial.print(F(" ms ] "));
Serial.print(F("Luminosity: "));
Serial.println(x, DEC);
}
/**************************************************************************/
/*
Show how to read IR and Full Spectrum at once and convert to lux
*/
/**************************************************************************/
void advancedRead(void)
{
// More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum
// That way you can do whatever math and comparisons you want!
uint32_t lum = tsl.getFullLuminosity();
uint16_t ir, full;
ir = lum >> 16;
full = lum & 0xFFFF;
Serial.print(F("[ ")); Serial.print(millis()); Serial.print(F(" ms ] "));
Serial.print(F("IR: ")); Serial.print(ir); Serial.print(F(" "));
Serial.print(F("Full: ")); Serial.print(full); Serial.print(F(" "));
Serial.print(F("Visible: ")); Serial.print(full - ir); Serial.print(F(" "));
Serial.print(F("Lux: ")); Serial.println(tsl.calculateLux(full, ir));
}
/**************************************************************************/
/*
Performs a read using the Adafruit Unified Sensor API.
*/
/**************************************************************************/
void unifiedSensorAPIRead(void)
{
/* Get a new sensor event */
sensors_event_t event;
tsl.getEvent(&event);
/* Display the results (light is measured in lux) */
Serial.print(F("[ ")); Serial.print(event.timestamp); Serial.print(F(" ms ] "));
if ((event.light == 0) |
(event.light > 4294966000.0) |
(event.light <-4294966000.0))
{
/* If event.light = 0 lux the sensor is probably saturated */
/* and no reliable data could be generated! */
/* if event.light is +/- 4294967040 there was a float over/underflow */
Serial.println(F("Invalid data (adjust gain or timing)"));
}
else
{
Serial.print(event.light); Serial.println(F(" lux"));
}
}
/**************************************************************************/
/*
Arduino loop function, called once 'setup' is complete (your own code
should go here)
*/
/**************************************************************************/
void loop(void)
{
//simpleRead();
advancedRead();
// unifiedSensorAPIRead();
delay(500);
}
@@ -0,0 +1,229 @@
/* TSL2591 Digital Light Sensor, example with (simple) interrupt support */
/* Dynamic Range: 600M:1 */
/* Maximum Lux: 88K */
/* This example shows how the interrupt system on the TLS2591
* can be used to detect a meaningful change in light levels.
*
* Two thresholds can be set:
*
* Lower Threshold - Any light sample on CHAN0 below this value
* will trigger an interrupt
* Upper Threshold - Any light sample on CHAN0 above this value
* will trigger an interrupt
*
* If CHAN0 (full light) crosses below the low threshold specified,
* or above the higher threshold, an interrupt is asserted on the interrupt
* pin. The use of the HW pin is optional, though, since the change can
* also be detected in software by looking at the status byte via
* tsl.getStatus().
*
* An optional third parameter can be used in the .registerInterrupt
* function to indicate the number of samples that must stay outside
* the threshold window before the interrupt fires, providing some basic
* debouncing of light level data.
*
* For example, the following code will fire an interrupt on any and every
* sample outside the window threshold (meaning a sample below 100 or above
* 1500 on CHAN0 or FULL light):
*
* tsl.registerInterrupt(100, 1500, TSL2591_PERSIST_ANY);
*
* This code would require five consecutive changes before the interrupt
* fires though (see tls2591Persist_t in Adafruit_TLS2591.h for possible
* values):
*
* tsl.registerInterrupt(100, 1500, TSL2591_PERSIST_5);
*/
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h"
// Example for demonstrating the TSL2591 library - public domain!
// connect SCL to analog 5
// connect SDA to analog 4
// connect Vin to 3.3-5V DC
// connect GROUND to common ground
// Interrupt thresholds and persistance
#define TLS2591_INT_THRESHOLD_LOWER (100)
#define TLS2591_INT_THRESHOLD_UPPER (1500)
//#define TLS2591_INT_PERSIST (TSL2591_PERSIST_ANY) // Fire on any valid change
#define TLS2591_INT_PERSIST (TSL2591_PERSIST_60) // Require at least 60 samples to fire
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)
/**************************************************************************/
/*
Displays some basic information on this sensor from the unified
sensor API sensor_t type (see Adafruit_Sensor for more information)
*/
/**************************************************************************/
void displaySensorDetails(void)
{
sensor_t sensor;
tsl.getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print ("Sensor: "); Serial.println(sensor.name);
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" lux");
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" lux");
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" lux");
Serial.println("------------------------------------");
Serial.println("");
delay(500);
}
/**************************************************************************/
/*
Configures the gain and integration time for the TSL2591
*/
/**************************************************************************/
void configureSensor(void)
{
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
//tsl.setGain(TSL2591_GAIN_LOW); // 1x gain (bright light)
tsl.setGain(TSL2591_GAIN_MED); // 25x gain
// tsl.setGain(TSL2591_GAIN_HIGH); // 428x gain
// Changing the integration time gives you a longer time over which to sense light
// longer timelines are slower, but are good in very low light situtations!
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); // shortest integration time (bright light)
// tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
// tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); // longest integration time (dim light)
/* Display the gain and integration time for reference sake */
Serial.println("------------------------------------");
Serial.print ("Gain: ");
tsl2591Gain_t gain = tsl.getGain();
switch (gain)
{
case TSL2591_GAIN_LOW:
Serial.println("1x (Low)");
break;
case TSL2591_GAIN_MED:
Serial.println("25x (Medium)");
break;
case TSL2591_GAIN_HIGH:
Serial.println("428x (High)");
break;
case TSL2591_GAIN_MAX:
Serial.println("9876x (Max)");
break;
}
Serial.print ("Timing: ");
Serial.print((tsl.getTiming() + 1) * 100, DEC);
Serial.println(" ms");
Serial.println("------------------------------------");
Serial.println("");
/* Setup the SW interrupt to trigger between 100 and 1500 lux */
/* Threshold values are defined at the top of this sketch */
tsl.clearInterrupt();
tsl.registerInterrupt(TLS2591_INT_THRESHOLD_LOWER,
TLS2591_INT_THRESHOLD_UPPER,
TLS2591_INT_PERSIST);
/* Display the interrupt threshold window */
Serial.print("Interrupt Threshold Window: -");
Serial.print(TLS2591_INT_THRESHOLD_LOWER, DEC);
Serial.print(" to +");
Serial.println(TLS2591_INT_THRESHOLD_LOWER, DEC);
Serial.println("");
}
/**************************************************************************/
/*
Program entry point for the Arduino sketch
*/
/**************************************************************************/
void setup(void)
{
Serial.begin(9600);
// Enable this line for Flora, Zero and Feather boards with no FTDI chip
// Waits for the serial port to connect before sending data out
// while (!Serial) { delay(1); }
Serial.println("Starting Adafruit TSL2591 interrupt Test!");
if (tsl.begin())
{
Serial.println("Found a TSL2591 sensor");
}
else
{
Serial.println("No sensor found ... check your wiring?");
while (1);
}
/* Display some basic information on this sensor */
displaySensorDetails();
/* Configure the sensor (including the interrupt threshold) */
configureSensor();
// Now we're ready to get readings ... move on to loop()!
}
/**************************************************************************/
/*
Show how to read IR and Full Spectrum at once and convert to lux
*/
/**************************************************************************/
void advancedRead(void)
{
// More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum
// That way you can do whatever math and comparisons you want!
uint32_t lum = tsl.getFullLuminosity();
uint16_t ir, full;
ir = lum >> 16;
full = lum & 0xFFFF;
Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
Serial.print("IR: "); Serial.print(ir); Serial.print(" ");
Serial.print("Full: "); Serial.print(full); Serial.print(" ");
Serial.print("Visible: "); Serial.print(full - ir); Serial.print(" ");
Serial.print("Lux: "); Serial.println(tsl.calculateLux(full, ir));
}
void getStatus(void)
{
uint8_t x = tsl.getStatus();
// bit 4: ALS Interrupt occured
// bit 5: No-persist Interrupt occurence
if (x & 0x10) {
Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
Serial.println("ALS Interrupt occured");
}
if (x & 0x20) {
Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
Serial.println("No-persist Interrupt occured");
}
// Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
Serial.print("Status: ");
Serial.println(x, BIN);
tsl.clearInterrupt();
}
/**************************************************************************/
/*
Arduino loop function, called once 'setup' is complete (your own code
should go here)
*/
/**************************************************************************/
void loop(void)
{
advancedRead();
getStatus();
delay(500);
}
+9
View File
@@ -0,0 +1,9 @@
name=Adafruit TSL2591 Library
version=1.0.2
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=Library for the TSL2591 digital luminosity (light) sensors.
paragraph=Library for the TSL2591 digital luminosity (light) sensors.
category=Sensors
url=https://github.com/adafruit/Adafruit_TSL2591_Library
architectures=*
+74
View File
@@ -0,0 +1,74 @@
/*
Name: PingTest.ino
Created: 05/08/2017 10:20:19
Author: pbecc
*/
#undef PROVA_
#include <WiFi.h>
#include "esp32_ping.h"
// the setup function runs once when you press reset or power the board
const char ssid[] = "TP-LINK_C20B"; // your network SSID (name)
const char password[] = "paolo-48"; // your network password
void setup() {
Serial.begin(115200);
Serial.print("Connecting t ");
Serial.println(ssid);
// WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Pinging address: 192.168.1.1");
}
// the loop function runs over and over again until power down or reset
void loop() {
int ia[4] = { 192,168,1,1 };
int i = 0;
while (Serial.available()) {
char c = Serial.read();
delay(100);
int val = 0;
while (c != '.' && c != 10 && c!=255) {
if (c >= '0'&& c<='9') {
val = val*10+(c-'0');
}
c = Serial.read();
}
ia[i++] =val ;
}
IPAddress adr = IPAddress(ia[0], ia[1], ia[2], ia[3]);
Serial.printf("Ping : %d . %d . %d . %d ->", ia[0], ia[1], ia[2], ia[3]);
if (ping_start(adr, 4, 0, 0, 5))
Serial.println("OK");
else
Serial.println("FAILED");
delay(10000);
}
int readnu(char s) {
char c = Serial.read();
Serial.print(c);
int digit = 1,val=0;
while (c != s && c != 10&&c>0) {
if(c>'0') val += digit*(c - '0');
digit *= 10;
c=Serial.read();
Serial.print(int(c));
}
Serial.println(digit);
return digit;
}
+4
View File
@@ -0,0 +1,4 @@
# ESP32_ping
Ping library for ESP32
WORK IN PROGRESS
+366
View File
@@ -0,0 +1,366 @@
/*
* ESP32 Ping library
*
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for any purpose and without fee is hereby
* granted, provided that the above copyright notice appear in all
* copies and that both that the copyright notice and this
* permission notice and warranty disclaimer appear in supporting
* documentation, and that the name of the author not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* The author disclaim all warranties with regard to this
* software, including all implied warranties of merchantability
* and fitness. In no event shall the author be liable for any
* special, indirect or consequential damages or any damages
* whatsoever resulting from loss of use, data or profits, whether
* in an action of contract, negligence or other tortious action,
* arising out of or in connection with the use or performance of
* this software.
*
* --------------------------------------------------------------------------------
* Ping Library is based on the following source code:
*
* Lua RTOS, ping utility
*
*
* Author: Jaume Oliv (jolive@iberoxarxa.com / jolive@whitecatboard.org)
*
* --------------------------------------------------------------------------------
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*/
#ifdef ESP32
#include <Arduino.h>
#include <math.h>
#include <float.h>
#include <signal.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include "esp32_ping.h"
#include "lwip/inet_chksum.h"
#include "lwip/ip.h"
#include "lwip/ip4.h"
#include "lwip/err.h"
#include "lwip/icmp.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"
static uint16_t ping_seq_num;
static uint8_t stopped = 0;
/*
* Statistics
*/
static uint32_t transmitted = 0;
static uint32_t received = 0;
static float min_time = 0;
static float max_time = 0;
static float mean_time = 0;
static float last_mean_time = 0;
static float var_time = 0;
#define PING_ID 0xAFAF
#define PING_DEFAULT_COUNT 10
#define PING_DEFAULT_INTERVAL 1
#define PING_DEFAULT_SIZE 32
#define PING_DEFAULT_TIMEOUT 1
/*
* Helper functions
*
*/
static void ping_prepare_echo(struct icmp_echo_hdr *iecho, uint16_t len) {
size_t i;
size_t data_len = len - sizeof(struct icmp_echo_hdr);
ICMPH_TYPE_SET(iecho, ICMP_ECHO);
ICMPH_CODE_SET(iecho, 0);
iecho->chksum = 0;
iecho->id = PING_ID;
iecho->seqno = htons(++ping_seq_num);
/* fill the additional data buffer with some data */
for (i = 0; i < data_len; i++) {
((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
}
iecho->chksum = inet_chksum(iecho, len);
}
static err_t ping_send(int s, ip4_addr_t *addr, int size) {
struct icmp_echo_hdr *iecho;
struct sockaddr_in to;
size_t ping_size = sizeof(struct icmp_echo_hdr) + size;
int err;
iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size);
if (!iecho) {
return ERR_MEM;
}
ping_prepare_echo(iecho, (uint16_t)ping_size);
to.sin_len = sizeof(to);
to.sin_family = AF_INET;
inet_addr_from_ipaddr(&to.sin_addr, addr);
if ((err = sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to)))) {
transmitted++;
}
return (err ? ERR_OK : ERR_VAL);
}
static void ping_recv(int s) {
char buf[64];
int fromlen, len;
struct sockaddr_in from;
struct ip_hdr *iphdr;
struct icmp_echo_hdr *iecho = NULL;
char ipa[16];
struct timeval begin;
struct timeval end;
uint64_t micros_begin;
uint64_t micros_end;
float elapsed;
// Register begin time
gettimeofday(&begin, NULL);
// Send
while ((len = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0) {
if (len >= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr))) {
// Register end time
gettimeofday(&end, NULL);
/// Get from IP address
ip4_addr_t fromaddr;
inet_addr_to_ipaddr(&fromaddr, &from.sin_addr);
strcpy(ipa, inet_ntoa(fromaddr));
// Get echo
iphdr = (struct ip_hdr *)buf;
iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4));
// Print ....
if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) {
received++;
// Get elapsed time in milliseconds
micros_begin = begin.tv_sec * 1000000;
micros_begin += begin.tv_usec;
micros_end = end.tv_sec * 1000000;
micros_end += end.tv_usec;
elapsed = (float)(micros_end - micros_begin) / (float)1000.0;
// Update statistics
// Mean and variance are computed in an incremental way
if (elapsed < min_time) {
min_time = elapsed;
}
if (elapsed > max_time) {
max_time = elapsed;
}
last_mean_time = mean_time;
mean_time = (((received - 1) * mean_time) + elapsed) / received;
if (received > 1) {
var_time = var_time + ((elapsed - last_mean_time) * (elapsed - mean_time));
}
// Print ...
log_d("%d bytes from %s: icmp_seq=%d time=%.3f ms\r\n", len, ipa,
ntohs(iecho->seqno), elapsed
);
return;
}
else {
// TODO
}
}
}
if (len < 0) {
log_d("Request timeout for icmp_seq %d\r\n", ping_seq_num);
}
}
/*
static void stop_action(int i) {
signal(i, SIG_DFL);
stopped = 1;
}
+/
/*
* Operation functions
*
*/
void ping(const char *name, int count, int interval, int size, int timeout) {
// Resolve name
hostent * target = gethostbyname(name);
IPAddress adr = *target->h_addr_list[0];
if (target->h_length == 0) {
// TODO: error not found target?????
return;
}
ping_start(adr, count, interval, size, timeout);
}
bool ping_start(struct ping_option *ping_o) {
return ping_start(ping_o->ip,ping_o->count,0,0,0);
}
bool ping_start(IPAddress adr, int count=0, int interval=0, int size=0, int timeout=0) {
// driver_error_t *error;
struct sockaddr_in address;
ip4_addr_t ping_target;
int s;
// Get default values if argument are not provided
if (count == 0) {
count = PING_DEFAULT_COUNT;
}
if (interval == 0) {
interval = PING_DEFAULT_INTERVAL;
}
if (size == 0) {
size = PING_DEFAULT_SIZE;
}
if (timeout == 0) {
timeout = PING_DEFAULT_TIMEOUT;
}
// Create socket
if ((s = socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) {
// TODO: error
return false;
}
address.sin_addr.s_addr = adr;
ping_target.addr = address.sin_addr.s_addr;
// Setup socket
struct timeval tout;
// Timeout
tout.tv_sec = timeout;
tout.tv_usec = 0;
if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tout, sizeof(tout)) < 0) {
closesocket(s);
// TODO: error
return false;
}
stopped = 0;
transmitted = 0;
received = 0;
min_time = 1.E+9;// FLT_MAX;
max_time = 0.0;
mean_time = 0.0;
var_time = 0.0;
// Register signal for stop ping
//signal(SIGINT, stop_action);
// Begin ping ...
char ipa[16];
strcpy(ipa, inet_ntoa(ping_target));
log_i("PING %s: %d data bytes\r\n", ipa, size);
ping_seq_num = 0;
while ((ping_seq_num < count) && (!stopped)) {
if (ping_send(s, &ping_target, size) == ERR_OK) {
ping_recv(s);
}
delay( interval*1000L);
}
closesocket(s);
log_i("%d packets transmitted, %d packets received, %.1f%% packet loss\r\n",
transmitted,
received,
((((float)transmitted - (float)received) / (float)transmitted) * 100.0)
);
if (received) {
ping_resp pingresp;
log_i("round-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms\r\n", min_time, mean_time, max_time, sqrt(var_time / received));
pingresp.total_count = 10;
pingresp.timeout_count = 10;
pingresp.total_bytes = 1;
pingresp.total_time = mean_time;
pingresp.ping_err = 0;
return true;
// ping_o->sent_function(ping_o, (uint8*)&pingresp);
}
return false;
}
bool ping_regist_recv(struct ping_option *ping_opt, ping_recv_function ping_recv)
{
if (ping_opt == NULL)
return false;
ping_opt->recv_function = ping_recv;
return true;
}
bool ping_regist_sent(struct ping_option *ping_opt, ping_sent_function ping_sent)
{
if (ping_opt == NULL)
return false;
ping_opt->sent_function = ping_sent;
return true;
}
#endif
+36
View File
@@ -0,0 +1,36 @@
#ifndef _PING_
#define _PING_
#include <Arduino.h>
#ifdef ESP32
typedef void(*ping_recv_function)(void* arg, void *pdata);
typedef void(*ping_sent_function)(void* arg, void *pdata);
struct ping_option {
uint32_t count;
uint32_t ip;
uint32_t coarse_time;
ping_recv_function recv_function;
ping_sent_function sent_function;
void* reverse;
};
struct ping_resp {
uint32_t total_count;
uint32_t resp_time;
uint32_t seqno;
uint32_t timeout_count;
uint32_t bytes;
uint32_t total_bytes;
uint32_t total_time;
int8_t ping_err;
};
bool ping_start(struct ping_option *ping_opt);
void ping(const char *name, int count, int interval, int size, int timeout);
bool ping_start(IPAddress adr, int count, int interval, int size, int timeout);
#endif
#endif
@@ -0,0 +1,241 @@
/*
ESPeasySoftwareSerial.cpp - Implementation of the Arduino software serial for ESP8266.
Copyright (c) 2015-2016 Peter Lerup. All rights reserved.
This library 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 2.1 of the License, or (at your option) any later version.
This library 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 this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
// The Arduino standard GPIO routines are not enough,
// must use some from the Espressif SDK as well
extern "C" {
#include "gpio.h"
}
#include <ESPeasySoftwareSerial.h>
#define MAX_PIN 15
#define USABLE_PINS 10
#define NR_CONCURRENT_SOFT_SERIALS 3
// As the Arduino attachInterrupt has no parameter, lists of objects
// and callbacks corresponding to each possible GPIO pins have to be defined
static ESPeasySoftwareSerial *ObjList[NR_CONCURRENT_SOFT_SERIALS];
static uint8_t PinControllerMap[NR_CONCURRENT_SOFT_SERIALS]={}; // Zero all elements
void ICACHE_RAM_ATTR sws_isr_0() { ObjList[0]->rxRead(); };
void ICACHE_RAM_ATTR sws_isr_1() { ObjList[1]->rxRead(); };
void ICACHE_RAM_ATTR sws_isr_2() { ObjList[2]->rxRead(); };
/*void ICACHE_RAM_ATTR sws_isr_3() { ObjList[3]->rxRead(); };
void ICACHE_RAM_ATTR sws_isr_4() { ObjList[4]->rxRead(); };
void ICACHE_RAM_ATTR sws_isr_5() { ObjList[5]->rxRead(); };
// Pin 6 to 11 can not be used
void ICACHE_RAM_ATTR sws_isr_12() { ObjList[6]->rxRead(); };
void ICACHE_RAM_ATTR sws_isr_13() { ObjList[7]->rxRead(); };
void ICACHE_RAM_ATTR sws_isr_14() { ObjList[8]->rxRead(); };
void ICACHE_RAM_ATTR sws_isr_15() { ObjList[9]->rxRead(); };
*/
static void (*ISRList[NR_CONCURRENT_SOFT_SERIALS])() = {
sws_isr_0,
sws_isr_1,
sws_isr_2 /*,
sws_isr_3,
sws_isr_4,
sws_isr_5,
// Pin 6 to 11 can not be used
sws_isr_12,
sws_isr_13,
sws_isr_14,
sws_isr_15
*/
};
ESPeasySoftwareSerial::ESPeasySoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic, uint16_t buffSize) {
m_rxValid = m_txValid = m_txEnableValid = false;
m_buffer = NULL;
m_invert = inverse_logic;
if (isValidGPIOpin(receivePin)) {
m_rxPin = receivePin;
m_buffSize = buffSize;
m_buffer = (uint8_t*)malloc(m_buffSize);
if (m_buffer != NULL) {
m_rxValid = true;
m_inPos = m_outPos = 0;
pinMode(m_rxPin, INPUT);
const uint8_t index = pinToIndex(m_rxPin);
if (index == NR_CONCURRENT_SOFT_SERIALS) {
return; // Not possible to add software Serial.
}
ObjList[index] = this;
enableRx(true);
}
}
if (isValidGPIOpin(transmitPin)) {
m_txValid = true;
m_txPin = transmitPin;
pinMode(m_txPin, OUTPUT);
digitalWrite(m_txPin, !m_invert);
}
// Default speed
begin(9600);
}
ESPeasySoftwareSerial::~ESPeasySoftwareSerial() {
enableRx(false);
if (m_rxValid) {
const uint8_t index = pinToIndex(m_rxPin);
if (index < NR_CONCURRENT_SOFT_SERIALS) {
PinControllerMap[index] = 0;
ObjList[index] = NULL;
}
}
if (m_buffer)
free(m_buffer);
}
bool ESPeasySoftwareSerial::isValidGPIOpin(uint8_t pin) {
if (pin >= 0 && pin <= 5) {
return true;
}
if (pin >= 12 && pin <= MAX_PIN) {
return true;
}
return false;
}
uint8_t ESPeasySoftwareSerial::pinToIndex(uint8_t pin) {
// Pin will be stored in the map, only "1" will be added,
// to allow simple initialize to 0 and still use GPIO-0.
const uint8_t stored_pin = pin + 1;
for (unsigned i = 0; i < NR_CONCURRENT_SOFT_SERIALS; ++i) {
if (PinControllerMap[i] == stored_pin) return i;
}
// Not found, add as first free option.
for (unsigned i = 0; i < NR_CONCURRENT_SOFT_SERIALS; ++i) {
if (PinControllerMap[i] == 0) {
PinControllerMap[i] = stored_pin;
return i;
}
}
// No more controllers available.
return NR_CONCURRENT_SOFT_SERIALS;
}
void ESPeasySoftwareSerial::begin(long speed) {
// Use getCycleCount() loop to get as exact timing as possible
m_bitTime = ESP.getCpuFreqMHz()*1000000/speed;
}
void ESPeasySoftwareSerial::setTransmitEnablePin(uint8_t transmitEnablePin) {
if (isValidGPIOpin(transmitEnablePin)) {
m_txEnableValid = true;
m_txEnablePin = transmitEnablePin;
pinMode(m_txEnablePin, OUTPUT);
digitalWrite(m_txEnablePin, LOW);
} else {
m_txEnableValid = false;
}
}
void ESPeasySoftwareSerial::enableRx(bool on) {
if (m_rxValid) {
if (on) {
attachInterrupt(m_rxPin, ISRList[pinToIndex(m_rxPin)], m_invert ? RISING : FALLING);
} else {
detachInterrupt(m_rxPin);
}
}
}
int ESPeasySoftwareSerial::read() {
if (!m_rxValid || (m_inPos == m_outPos)) return -1;
uint8_t ch = m_buffer[m_outPos];
m_outPos = (m_outPos+1) % m_buffSize;
return ch;
}
int ESPeasySoftwareSerial::available() {
if (!m_rxValid) return 0;
int avail = m_inPos - m_outPos;
if (avail < 0) avail += m_buffSize;
return avail;
}
#define WAIT { while (ESP.getCycleCount()-start < wait); wait += m_bitTime; }
size_t ESPeasySoftwareSerial::write(uint8_t b) {
if (!m_txValid) return 0;
if (m_invert) b = ~b;
// Disable interrupts in order to get a clean transmit
cli();
if (m_txEnableValid) digitalWrite(m_txEnablePin, HIGH);
unsigned long wait = m_bitTime;
digitalWrite(m_txPin, HIGH);
unsigned long start = ESP.getCycleCount();
// Start bit;
digitalWrite(m_txPin, LOW);
WAIT;
for (int i = 0; i < 8; i++) {
digitalWrite(m_txPin, (b & 1) ? HIGH : LOW);
WAIT;
b >>= 1;
}
// Stop bit
digitalWrite(m_txPin, HIGH);
WAIT;
if (m_txEnableValid) digitalWrite(m_txEnablePin, LOW);
sei();
return 1;
}
void ESPeasySoftwareSerial::flush() {
m_inPos = m_outPos = 0;
}
int ESPeasySoftwareSerial::peek() {
if (!m_rxValid || (m_inPos == m_outPos)) return -1;
return m_buffer[m_outPos];
}
void ICACHE_RAM_ATTR ESPeasySoftwareSerial::rxRead() {
// Advance the starting point for the samples but compensate for the
// initial delay which occurs before the interrupt is delivered
unsigned long wait = m_bitTime + m_bitTime/3 - 500;
unsigned long start = ESP.getCycleCount();
uint8_t rec = 0;
for (uint8_t i = 0; i < 8; i++) {
WAIT;
rec >>= 1;
if (digitalRead(m_rxPin))
rec |= 0x80;
}
if (m_invert) rec = ~rec;
// Stop bit
WAIT;
// Store the received value in the buffer unless we have an overflow
uint16_t next = (m_inPos+1) % m_buffSize;
if (next != m_inPos) {
m_buffer[m_inPos] = rec;
m_inPos = next;
}
// Must clear this bit in the interrupt register,
// it gets set even when interrupts are disabled
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << m_rxPin);
}
@@ -0,0 +1,78 @@
/*
ESPeasySoftwareSerial.h
ESPeasySoftwareSerial.cpp - Implementation of the Arduino software serial for ESP8266.
Copyright (c) 2015-2016 Peter Lerup. All rights reserved.
This library 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 2.1 of the License, or (at your option) any later version.
This library 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 this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ESPeasySoftwareSerial_h
#define ESPeasySoftwareSerial_h
#include <inttypes.h>
#include <Stream.h>
// This class is compatible with the corresponding AVR one,
// the constructor however has an optional rx buffer size.
// Speed up to 115200 can be used.
class ESPeasySoftwareSerial : public Stream
{
public:
ESPeasySoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false, uint16_t buffSize = 64);
virtual ~ESPeasySoftwareSerial();
void begin(long speed);
void setTransmitEnablePin(uint8_t transmitEnablePin);
int peek();
virtual size_t write(uint8_t byte);
virtual int read();
virtual int available();
virtual void flush();
operator bool() {return m_rxValid || m_txValid;}
// Disable or enable interrupts on the rx pin
void enableRx(bool on);
void rxRead();
using Print::write;
private:
bool isValidGPIOpin(uint8_t pin);
uint8_t pinToIndex(uint8_t pin);
// Member variables
uint8_t m_rxPin, m_txPin, m_txEnablePin;
bool m_rxValid, m_txValid, m_txEnableValid;
bool m_invert;
unsigned long m_bitTime;
uint16_t m_inPos, m_outPos;
uint16_t m_buffSize;
uint8_t *m_buffer;
};
// If only one tx or rx wanted then use this as parameter for the unused pin
#define SW_SERIAL_UNUSED_PIN -1
#endif
+11
View File
@@ -0,0 +1,11 @@
# EspESPeasySoftwareSerial
Implementation of the Arduino software serial library for the ESP8266
Same functionality as the corresponding AVR library but several instances can be active at the same time.
Speed up to 115200 baud is supported. The constructor also has an optional input buffer size.
Please note that due to the fact that the ESP always have other activities ongoing, there will be some inexactness in interrupt
timings. This may lead to bit errors when having heavy data traffic in high baud rates.
@@ -0,0 +1,27 @@
#include <ESPeasySoftwareSerial.h>
ESPeasySoftwareSerial swSer(14, 12, false, 256);
void setup() {
Serial.begin(115200);
swSer.begin(115200);
Serial.println("\nSoftware serial test started");
for (char ch = ' '; ch <= 'z'; ch++) {
swSer.write(ch);
}
swSer.println("");
}
void loop() {
while (swSer.available() > 0) {
Serial.write(swSer.read());
}
while (Serial.available() > 0) {
swSer.write(Serial.read());
}
}
+31
View File
@@ -0,0 +1,31 @@
#######################################
# Syntax Coloring Map for ESPeasySoftwareSerial
# (esp8266)
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
ESPeasySoftwareSerial KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
read KEYWORD2
write KEYWORD2
available KEYWORD2
flush KEYWORD2
overflow KEYWORD2
peek KEYWORD2
listen KEYWORD2
end KEYWORD2
isListening KEYWORD2
stopListening KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
+15
View File
@@ -0,0 +1,15 @@
{
"name": "EspESPeasySoftwareSerial",
"version": "3.3.1",
"keywords": [
"serial", "io", "softwareserial"
],
"description": "Implementation of the Arduino software serial for ESP8266. Adjusted to reduce memory footprint for ESPeasy",
"repository":
{
"type": "git",
"url": "https://github.com/plerup/espsoftwareserial"
},
"frameworks": "arduino",
"platforms": "espressif8266"
}
@@ -0,0 +1,9 @@
name=ESPeasySoftwareSerial
version=1.0
author=Peter Lerup
maintainer=Peter Lerup <peter@lerup.com>
sentence=Implementation of the Arduino software serial for ESP8266.
paragraph=
category=Signal Input/Output
url=
architectures=esp8266
+456
View File
@@ -0,0 +1,456 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. 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 not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the 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
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
+40
View File
@@ -0,0 +1,40 @@
# ESP8266Ping
Let the ESP8266 ping a remote machine.
With this library an ESP8266 can ping a remote machine and know if it's reachable.
It provide some basic measurements on ping messages (avg response time).
## Usage
First, include the library in your sketch along with WiFi library:
```Arduino
#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>
```
Next, simply call the `Ping.ping()` function
```Arduino
IPAddress ip (192, 168, 0, 1); // The remote ip to ping
bool ret = Ping.ping(ip);
```
`ret` will be true if the remote responded to pings, false if not reachable.
The library supports hostname too, just pass a string instead of the ip address:
```Arduino
bool ret = Ping.ping("www.google.com");
```
Additionally, the function accept a second integer parameter `count` that specify how many pings has to be sent:
```Arduino
bool ret = Ping.ping(ip_or_host, 10);
```
After `Ping.ping()` has been called, the average response time (in milliseconds) can be retrieved with
```Arduino
int avg_time_ms = Ping.averageTime();
```
@@ -0,0 +1,43 @@
/*
* This example show how to ping a remote machine using it's hostname
*/
#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>
const char* ssid = "ssid";
const char* password = "passphrase";
const char* remote_host = "www.google.com";
void setup() {
Serial.begin(115200);
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.println("Connecting to WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println();
Serial.print("WiFi connected with ip ");
Serial.println(WiFi.localIP());
Serial.print("Pinging host ");
Serial.println(remote_host);
if(Ping.ping(remote_host)) {
Serial.println("Success!!");
} else {
Serial.println("Error :(");
}
}
void loop() { }
@@ -0,0 +1,44 @@
/*
* With this library an ESP8266 can ping a remote machine and know if it's reachable.
* It provides some basic measurements on ping messages (avg response time).
*/
#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>
const char* ssid = "ssid";
const char* password = "passphrase";
const IPAddress remote_ip(192, 168, 0, 1);
void setup() {
Serial.begin(115200);
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.println("Connecting to WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println();
Serial.print("WiFi connected with ip ");
Serial.println(WiFi.localIP());
Serial.print("Pinging ip ");
Serial.println(remote_ip);
if(Ping.ping(remote_ip)) {
Serial.println("Success!!");
} else {
Serial.println("Error :(");
}
}
void loop() { }
+26
View File
@@ -0,0 +1,26 @@
#######################################
# Syntax Coloring Map For ESP8266Ping
#######################################
#######################################
# Library (KEYWORD3)
#######################################
ESP8266Ping KEYWORD3
#######################################
# Datatypes (KEYWORD1)
#######################################
Ping KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
ping KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
@@ -0,0 +1,9 @@
name=ESPEasy_ESP8266Ping
version=1.0
author=Daniele Colanardi
maintainer=Daniele Colanardi <dancol90@gmail.com>
sentence=Let the ESP8266 ping a remote machine.
paragraph=With this library an ESP8266 can ping a remote machine and know if it's reachable. It provide some basic measurements on ping messages (avg response time). Lib name renamed to avoid conflicts in Arduino IDE.
category=Communication
url=
architectures=esp8266
+61
View File
@@ -0,0 +1,61 @@
/*
ESP8266Ping - Ping library for ESP8266
Copyright (c) 2015 Daniele Colanardi. All rights reserved.
This library 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 2.1 of the License, or (at your option) any later version.
This library 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 this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ESP8266Ping_H
#define ESP8266Ping_H
#if defined(ESP8266)
#include <Arduino.h>
#include <ESP8266WiFi.h>
extern "C" {
#include <ping.h>
}
#ifdef ENABLE_DEBUG_PING
#define DEBUG_PING(...) Serial.printf(__VA_ARGS__)
#else
#define DEBUG_PING(...)
#endif
class PingClass {
public:
PingClass();
bool ping(IPAddress dest, byte count = 5);
bool ping(const char* host, byte count = 5);
int averageTime();
protected:
static void _ping_sent_cb(void *opt, void *pdata);
static void _ping_recv_cb(void *opt, void *pdata);
IPAddress _dest;
ping_option _options;
static byte _expected_count, _errors, _success;
static int _avg_time;
};
#include "ESP8266Ping.impl.h"
PingClass Ping;
#endif
#endif
@@ -0,0 +1,112 @@
/*
ESP8266Ping - Ping library for ESP8266
Copyright (c) 2015 Daniele Colanardi. All rights reserved.
This library 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 2.1 of the License, or (at your option) any later version.
This library 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 this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
extern "C" void esp_schedule();
extern "C" void esp_yield();
PingClass::PingClass() {}
bool PingClass::ping(IPAddress dest, byte count) {
_expected_count = count;
_errors = 0;
_success = 0;
_avg_time = 0;
memset(&_options, 0, sizeof(struct ping_option));
// Repeat count (how many time send a ping message to destination)
_options.count = count;
// Time interval between two ping (seconds??)
_options.coarse_time = 1;
// Destination machine
_options.ip = dest;
// Callbacks
_options.recv_function = reinterpret_cast<ping_recv_function>(&PingClass::_ping_recv_cb);
_options.sent_function = NULL; //reinterpret_cast<ping_sent_function>(&_ping_sent_cb);
// Let's go!
if(ping_start(&_options)) {
// Suspend till the process end
esp_yield();
}
return (_success > 0);
}
bool PingClass::ping(const char* host, byte count) {
IPAddress remote_addr;
if (WiFi.hostByName(host, remote_addr))
return ping(remote_addr, count);
return false;
}
int PingClass::averageTime() {
return _avg_time;
}
void PingClass::_ping_recv_cb(void *opt, void *resp) {
// Cast the parameters to get some usable info
ping_resp* ping_resp = reinterpret_cast<struct ping_resp*>(resp);
//ping_option* ping_opt = reinterpret_cast<struct ping_option*>(opt);
// Error or success?
if (ping_resp->ping_err == -1)
_errors++;
else {
_success++;
_avg_time += ping_resp->resp_time;
}
// Some debug info
DEBUG_PING(
"DEBUG: ping reply\n"
"\ttotal_count = %d \n"
"\tresp_time = %d \n"
"\tseqno = %d \n"
"\ttimeout_count = %d \n"
"\tbytes = %d \n"
"\ttotal_bytes = %d \n"
"\ttotal_time = %d \n"
"\tping_err = %d \n",
ping_resp->total_count, ping_resp->resp_time, ping_resp->seqno,
ping_resp->timeout_count, ping_resp->bytes, ping_resp->total_bytes,
ping_resp->total_time, ping_resp->ping_err
);
// Is it time to end?
// Don't using seqno because it does not increase on error
if (_success + _errors == _expected_count) {
_avg_time = _avg_time / _expected_count;
DEBUG_PING("Avg resp time %d ms\n", _avg_time);
// Done, return to main functiom
esp_schedule();
}
}
byte PingClass::_expected_count = 0;
byte PingClass::_errors = 0;
byte PingClass::_success = 0;
int PingClass::_avg_time = 0;
+4 -4
View File
@@ -93,8 +93,8 @@ bool ICACHE_FLASH_ATTR IRKelvinatorAC::getPower() {
// Set the temp. in deg C
void ICACHE_FLASH_ATTR IRKelvinatorAC::setTemp(uint8_t temp) {
temp = max(KELVINATOR_MIN_TEMP, temp);
temp = min(KELVINATOR_MAX_TEMP, temp);
temp = max(static_cast<uint8_t>(KELVINATOR_MIN_TEMP), temp);
temp = min(static_cast<uint8_t>(KELVINATOR_MAX_TEMP), temp);
remote_state[1] = (remote_state[1] & 0xF0U) | (temp - KELVINATOR_MIN_TEMP);
remote_state[9] = remote_state[1]; // Duplicate to the 2nd command chunk.
}
@@ -106,12 +106,12 @@ uint8_t ICACHE_FLASH_ATTR IRKelvinatorAC::getTemp() {
// Set the speed of the fan, 0-5, 0 is auto, 1-5 is the speed
void ICACHE_FLASH_ATTR IRKelvinatorAC::setFan(uint8_t fan) {
fan = min(KELVINATOR_FAN_MAX, fan); // Bounds check
fan = min(static_cast<uint8_t>(KELVINATOR_FAN_MAX), fan); // Bounds check
// Only change things if we need to.
if (fan != getFan()) {
// Set the basic fan values.
uint8_t fan_basic = min(KELVINATOR_BASIC_FAN_MAX, fan);
uint8_t fan_basic = min(static_cast<uint8_t>(KELVINATOR_BASIC_FAN_MAX), fan);
remote_state[0] = (remote_state[0] & KELVINATOR_BASIC_FAN_MASK) |
(fan_basic << KELVINATOR_FAN_OFFSET);
remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk.
+3 -3
View File
@@ -77,8 +77,8 @@ bool ICACHE_FLASH_ATTR IRMitsubishiAC::getPower() {
// Set the temp. in deg C
void ICACHE_FLASH_ATTR IRMitsubishiAC::setTemp(uint8_t temp) {
temp = max(MITSUBISHI_AC_MIN_TEMP, temp);
temp = min(MITSUBISHI_AC_MAX_TEMP, temp);
temp = max(static_cast<uint8_t>(MITSUBISHI_AC_MIN_TEMP), temp);
temp = min(static_cast<uint8_t>(MITSUBISHI_AC_MAX_TEMP), temp);
remote_state[7] = temp - MITSUBISHI_AC_MIN_TEMP;
}
@@ -136,7 +136,7 @@ void ICACHE_FLASH_ATTR IRMitsubishiAC::setMode(uint8_t mode) {
// Set the requested vane operation mode of the a/c unit.
void ICACHE_FLASH_ATTR IRMitsubishiAC::setVane(uint8_t mode) {
mode = max(mode, B111); // bounds check
mode = max(mode, static_cast<uint8_t>(B111)); // bounds check
mode |= B1000;
mode <<= 3;
remote_state[9] |= mode;
+52 -7
View File
@@ -155,7 +155,7 @@ void ICACHE_FLASH_ATTR IRsend::sendNEC (unsigned long data, int nbits,
// Footer
mark(NEC_BIT_MARK);
// Gap to next command.
space(max(0, NEC_MIN_COMMAND_LENGTH - usecs.elapsed()));
space(max(0ul, NEC_MIN_COMMAND_LENGTH - usecs.elapsed()));
// Optional command repeat sequence.
for (unsigned int i = 0; i < repeat; i++) {
@@ -164,7 +164,52 @@ void ICACHE_FLASH_ATTR IRsend::sendNEC (unsigned long data, int nbits,
space(NEC_RPT_SPACE);
mark(NEC_BIT_MARK);
// Gap till next command.
space(max(0, NEC_MIN_COMMAND_LENGTH - usecs.elapsed()));
space(max(0ul, NEC_MIN_COMMAND_LENGTH - usecs.elapsed()));
}
}
void ICACHE_FLASH_ATTR IRsend::sendPioneer (unsigned long data, int nbits,
unsigned int repeat, unsigned long secondData) {
// Details about timings can be found at:
// http://www.sbprojects.com/knowledge/ir/nec.php
// More about the pioneer format:
// http://www.adrian-kingston.com/IRFormatPioneer.htm
// Set IR carrier frequency
enableIROut(40);
IRtimer usecs = IRtimer();
for (unsigned int i = 0; i <= repeat; i++) {
usecs.reset();
// Header
mark(PIONEER_HDR_MARK);
space(PIONEER_HDR_SPACE);
sendData(PIONEER_BIT_MARK, PIONEER_ONE_SPACE, PIONEER_BIT_MARK, PIONEER_ZERO_SPACE,
data, nbits, true);
// Footer
mark(PIONEER_BIT_MARK);
space(PIONEER_ONE_SPACE);
// Gap till next command.
space(max(0ul, PIONEER_MIN_COMMAND_LENGTH - usecs.elapsed()));
// Some Pioneer signals have two 32 bit commands
if (secondData) {
usecs.reset();
// Header
mark(PIONEER_HDR_MARK);
space(PIONEER_HDR_SPACE);
sendData(PIONEER_BIT_MARK, PIONEER_ONE_SPACE, PIONEER_BIT_MARK, PIONEER_ZERO_SPACE,
secondData, nbits, true);
// Footer
mark(PIONEER_BIT_MARK);
space(PIONEER_ONE_SPACE);
// Gap till next command.
space(max(0ul, PIONEER_MIN_COMMAND_LENGTH - usecs.elapsed()));
}
}
}
@@ -236,7 +281,7 @@ void ICACHE_FLASH_ATTR IRsend::sendSony(unsigned long data, int nbits,
// Footer
// The Sony protocol requires us to wait 45ms from start of a code to the
// start of the next one. A 10ms minimum gap is also required.
space(max(10000, 45000 - usecs.elapsed()));
space(max(10000u, 45000 - usecs.elapsed()));
}
// A space() is always performed last, so no need to turn off the LED.
}
@@ -367,7 +412,7 @@ void ICACHE_FLASH_ATTR IRsend::sendRCMM(uint32_t data, uint8_t nbits) {
mark(RCMM_BIT_MARK);
// Protocol requires us to wait at least RCMM_RPT_LENGTH usecs from the start
// or RCMM_MIN_GAP usecs.
space(max(RCMM_RPT_LENGTH - usecs.elapsed(), RCMM_MIN_GAP));
space(max(RCMM_RPT_LENGTH - usecs.elapsed(), static_cast<uint32_t>(RCMM_MIN_GAP)));
}
void ICACHE_FLASH_ATTR IRsend::sendPanasonic(unsigned int address,
@@ -415,7 +460,7 @@ void ICACHE_FLASH_ATTR IRsend::sendJVC(unsigned long data, int nbits,
// Footer
mark(JVC_BIT_MARK);
// Wait till the end of the repeat time window before we send another code.
space(max(0, JVC_RPT_LENGTH - usecs.elapsed()));
space(max(0u, JVC_RPT_LENGTH - usecs.elapsed()));
usecs.reset();
}
// No need to turn off the LED as we will always end with a space().
@@ -647,7 +692,7 @@ void ICACHE_FLASH_ATTR IRsend::sendSherwood(unsigned long data, int nbits,
unsigned int repeat) {
// Sherwood remote codes appear to be NEC codes with a manditory repeat code.
// i.e. repeat should be >= 1.
sendNEC(data, nbits, max(1, repeat));
sendNEC(data, nbits, max(1u, repeat));
}
void ICACHE_FLASH_ATTR IRsend::sendMitsubishiAC(unsigned char data[]) {
@@ -911,7 +956,7 @@ bool ICACHE_FLASH_ATTR IRrecv::decode(decode_results *results,
// Nr. of ticks.
uint32_t IRrecv::ticksLow(uint32_t usecs, uint8_t tolerance) {
// max() used to ensure the result can't drop below 0 before the cast.
return((uint32_t) max(usecs * (1.0 - tolerance/100.)/USECPERTICK, 0));
return((uint32_t) max(usecs * (1.0 - tolerance/100.)/USECPERTICK, 0.0));
}
// Calculate the upper bound of the nr. of ticks.
+4
View File
@@ -53,6 +53,7 @@ enum decode_type_t {
RC5,
RC6,
NEC,
PIONEER,
SONY,
PANASONIC,
JVC,
@@ -92,6 +93,7 @@ public:
#define REPEAT 0xffffffff
#define SEND_PROTOCOL_NEC case NEC: sendNEC(data, nbits); break;
#define SEND_PROTOCOL_PIONEER case PIONEER: sendPioneer(data, nbits, 1, 0ul); 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;
@@ -162,6 +164,7 @@ public:
void send(int type, unsigned long data, int nbits) {
switch (type) {
SEND_PROTOCOL_NEC
SEND_PROTOCOL_PIONEER
SEND_PROTOCOL_SONY
SEND_PROTOCOL_RC5
SEND_PROTOCOL_RC6
@@ -179,6 +182,7 @@ public:
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 sendPioneer(unsigned long data, int nbits=32, unsigned int repeat=0, unsigned long secondData=0ul);
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)
+8
View File
@@ -60,6 +60,14 @@
#define NEC_RPT_SPACE 2250
#define NEC_MIN_COMMAND_LENGTH 108000UL
#define PIONEER_HDR_MARK 8000
#define PIONEER_HDR_SPACE 4000
#define PIONEER_BIT_MARK 500
#define PIONEER_ONE_SPACE 1500
#define PIONEER_ZERO_SPACE 500
#define PIONEER_RPT_SPACE 2250
#define PIONEER_MIN_COMMAND_LENGTH 90000UL
// Timings based on http://www.sbprojects.com/knowledge/ir/sirc.php
#define SONY_HDR_MARK 2400
#define SONY_HDR_SPACE 600
+21 -11
View File
@@ -1,11 +1,4 @@
//www.DFRobot.com
//last updated on 21/12/2011
//Tim Starling Fix the reset bug (Thanks Tim)
//wiki doc http://www.dfrobot.com/wiki/index.php?title=I2C/TWI_LCD1602_Module_(SKU:_DFR0063)
//Support Forum: http://www.dfrobot.com/forum/
//Compatible with the Arduino IDE 1.0
//Library version:1.1
// Based on the work by DFRobot
#include "LiquidCrystal_I2C.h"
#include <inttypes.h>
@@ -16,7 +9,7 @@
#define printIIC(args) Wire.write(args)
inline size_t LiquidCrystal_I2C::write(uint8_t value) {
send(value, Rs);
return 0;
return 1;
}
#else
@@ -59,6 +52,11 @@ LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t l
_backlightval = LCD_NOBACKLIGHT;
}
void LiquidCrystal_I2C::oled_init(){
_oled = true;
init_priv();
}
void LiquidCrystal_I2C::init(){
init_priv();
}
@@ -134,6 +132,7 @@ void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
void LiquidCrystal_I2C::clear(){
command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero
delayMicroseconds(2000); // this command takes a long time!
if (_oled) setCursor(0,0);
}
void LiquidCrystal_I2C::home(){
@@ -221,6 +220,15 @@ void LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) {
}
}
//createChar with PROGMEM input
void LiquidCrystal_I2C::createChar(uint8_t location, const char *charmap) {
location &= 0x7; // we only have 8 locations 0-7
command(LCD_SETCGRAMADDR | (location << 3));
for (int i=0; i<8; i++) {
write(pgm_read_byte_near(charmap++));
}
}
// Turn the (optional) backlight off/on
void LiquidCrystal_I2C::noBacklight(void) {
_backlightval=LCD_NOBACKLIGHT;
@@ -309,6 +317,8 @@ void LiquidCrystal_I2C::printstr(const char c[]){
// unsupported API functions
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
void LiquidCrystal_I2C::off(){}
void LiquidCrystal_I2C::on(){}
void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {}
@@ -318,5 +328,5 @@ uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype){return 0;}
void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){}
void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){}
void LiquidCrystal_I2C::setContrast(uint8_t new_val){}
#pragma GCC diagnostic pop
+7 -2
View File
@@ -1,4 +1,4 @@
//DFRobot.com
//YWROBOT
#ifndef LiquidCrystal_I2C_h
#define LiquidCrystal_I2C_h
@@ -77,14 +77,18 @@ public:
void autoscroll();
void noAutoscroll();
void createChar(uint8_t, uint8_t[]);
void createChar(uint8_t location, const char *charmap);
// Example: const char bell[8] PROGMEM = {B00100,B01110,B01110,B01110,B11111,B00000,B00100,B00000};
void setCursor(uint8_t, uint8_t);
#if defined(ARDUINO) && ARDUINO >= 100
#if defined(ARDUINO) && ARDUINO >= 100
virtual size_t write(uint8_t);
#else
virtual void write(uint8_t);
#endif
void command(uint8_t);
void init();
void oled_init();
////compatibility API function aliases
void blink_on(); // alias for blink()
@@ -118,6 +122,7 @@ private:
uint8_t _displaycontrol;
uint8_t _displaymode;
uint8_t _numlines;
bool _oled = false;
uint8_t _cols;
uint8_t _rows;
uint8_t _backlightval;
+2
View File
@@ -0,0 +1,2 @@
# LiquidCrystal_I2C
LiquidCrystal Arduino library for the DFRobot I2C LCD displays
-69
View File
@@ -1,69 +0,0 @@
1,6c1
< //www.DFRobot.com
< //last updated on 26/11/2010
< //Tim Starling Fix the reset bug (Thanks Tim)
< //wiki doc http://www.dfrobot.com/wiki/index.php?title=I2C/TWI_LCD1602_Module_(SKU:_DFR0063)
< //Support Forum: http://www.dfrobot.com/forum/
<
---
> // LiquidCrystal_I2C V2.0
10d4
< #include "WProgram.h"
12c6
<
---
> #include "Arduino.h"
67c61
< delay(50);
---
> delayMicroseconds(50000);
77,90c71,84
< // we start in 8bit mode, try to set 4 bit mode
< write4bits(0x03 << 4);
< delayMicroseconds(4500); // wait min 4.1ms
<
< // second try
< write4bits(0x03 << 4);
< delayMicroseconds(4500); // wait min 4.1ms
<
< // third go!
< write4bits(0x03 << 4);
< delayMicroseconds(150);
<
< // finally, set to 4-bit interface
< write4bits(0x02 << 4);
---
> // we start in 8bit mode, try to set 4 bit mode
> write4bits(0x03);
> delayMicroseconds(4500); // wait min 4.1ms
>
> // second try
> write4bits(0x03);
> delayMicroseconds(4500); // wait min 4.1ms
>
> // third go!
> write4bits(0x03);
> delayMicroseconds(150);
>
> // finally, set to 4-bit interface
> write4bits(0x02);
225c219
< inline void LiquidCrystal_I2C::write(uint8_t value) {
---
> inline size_t LiquidCrystal_I2C::write(uint8_t value) {
226a221
> return 0;
235,238c230,233
< uint8_t highnib=value&0xf0;
< uint8_t lownib=(value<<4)&0xf0;
< write4bits((highnib)|mode);
< write4bits((lownib)|mode);
---
> uint8_t highnib=value>>4;
> uint8_t lownib=value & 0x0F;
> write4bits((highnib)|mode);
> write4bits((lownib)|mode);
248c243
< Wire.send((int)(_data) | _backlightval);
---
> Wire.write((int)(_data) | _backlightval);
+4 -4
View File
@@ -1,4 +1,4 @@
//DFRobot.com
//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h>
@@ -19,7 +19,7 @@ uint8_t check[8] = {0x0,0x1,0x3,0x16,0x1c,0x8,0x0};
uint8_t cross[8] = {0x0,0x1b,0xe,0x4,0xe,0x1b,0x0};
uint8_t retarrow[8] = { 0x1,0x1,0x5,0x9,0x1f,0x8,0x4};
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
void setup()
{
@@ -52,7 +52,7 @@ void displayKeyCodes(void) {
while (1) {
lcd.clear();
lcd.print("Codes 0x"); lcd.print(i, HEX);
lcd.print("-0x"); lcd.print(i+16, HEX);
lcd.print("-0x"); lcd.print(i+15, HEX);
lcd.setCursor(0, 1);
for (int j=0; j<16; j++) {
lcd.printByte(i+j);
@@ -67,4 +67,4 @@ void loop()
{
}
+11 -3
View File
@@ -1,20 +1,28 @@
//DFRobot.com
//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
void setup()
{
lcd.init(); // initialize the lcd
lcd.init();
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(3,0);
lcd.print("Hello, world!");
lcd.setCursor(2,1);
lcd.print("Ywrobot Arduino!");
lcd.setCursor(0,2);
lcd.print("Arduino LCM IIC 2004");
lcd.setCursor(2,3);
lcd.print("Power By Ec-yuan!");
}
void loop()
{
}
+2 -2
View File
@@ -1,14 +1,14 @@
/*
* Displays text sent over the serial port (e.g. from the Serial Monitor) on
* an attached LCD.
* DFRobot.com
* YWROBOT
*Compatible with the Arduino IDE 1.0
*Library version:1.1
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
void setup()
{
View File
+16
View File
@@ -0,0 +1,16 @@
{
"name": "LiquidCrystal_I2C",
"keywords": "LCD, liquidcrystal, I2C",
"description": "A library for DFRobot I2C LCD displays",
"repository":
{
"type": "git",
"url": "https://github.com/marcoschwartz/LiquidCrystal_I2C.git"
},
"frameworks": "arduino",
"platforms":
[
"atmelavr",
"espressif8266"
]
}
+9
View File
@@ -0,0 +1,9 @@
name=LiquidCrystal_I2C
version=1.1.4
author=Frank de Brabander
maintainer=Marco Schwartz <marcolivier.schwartz@gmail.com>
sentence=A library for I2C LCD displays.
paragraph= The library allows to control I2C displays with functions extremely similar to LiquidCrystal library. THIS LIBRARY MIGHT NOT BE COMPATIBLE WITH EXISTING SKETCHES.
category=Display
url=https://github.com/marcoschwartz/LiquidCrystal_I2C
architectures=avr
+7 -7
View File
@@ -26,7 +26,7 @@
#include <SensorSerial.h>
SensorSerial::SensorSerial(int receivePin, int transmitPin, bool inverse_logic, unsigned int buffSize) : SoftwareSerial(receivePin, transmitPin, inverse_logic, buffSize)
SensorSerial::SensorSerial(int receivePin, int transmitPin, bool inverse_logic, unsigned int buffSize) : ESPeasySoftwareSerial(receivePin, transmitPin, inverse_logic, buffSize)
{
//boolean sws = isValidGPIOpin(receivePin);
_hw = receivePin < 0;
@@ -37,7 +37,7 @@ void SensorSerial::begin(long speed)
if (_hw)
Serial.begin(speed);
else
SoftwareSerial::begin(speed);
ESPeasySoftwareSerial::begin(speed);
}
int SensorSerial::peek()
@@ -45,7 +45,7 @@ int SensorSerial::peek()
if (_hw)
return Serial.peek();
else
return SoftwareSerial::peek();
return ESPeasySoftwareSerial::peek();
}
size_t SensorSerial::write(uint8_t byte)
@@ -53,7 +53,7 @@ size_t SensorSerial::write(uint8_t byte)
if (_hw)
return Serial.write(byte);
else
return SoftwareSerial::write(byte);
return ESPeasySoftwareSerial::write(byte);
}
int SensorSerial::read()
@@ -61,7 +61,7 @@ int SensorSerial::read()
if (_hw)
return Serial.read();
else
return SoftwareSerial::read();
return ESPeasySoftwareSerial::read();
}
int SensorSerial::available()
@@ -69,7 +69,7 @@ int SensorSerial::available()
if (_hw)
return Serial.available();
else
return SoftwareSerial::available();
return ESPeasySoftwareSerial::available();
}
void SensorSerial::flush()
@@ -77,5 +77,5 @@ void SensorSerial::flush()
if (_hw)
Serial.flush();
else
SoftwareSerial::flush();
ESPeasySoftwareSerial::flush();
}
+2 -2
View File
@@ -27,9 +27,9 @@
#define _SENSORSERIAL_H_
#include "Arduino.h"
#include <SoftwareSerial.h>
#include <ESPeasySoftwareSerial.h>
class SensorSerial : public SoftwareSerial
class SensorSerial : public ESPeasySoftwareSerial
{
public:
SensorSerial(int receivePin, int transmitPin = -1, bool inverse_logic = false, unsigned int buffSize = 64);
+116 -29
View File
@@ -25,7 +25,7 @@
#include "jkSDS011.h"
CjkSDS011::CjkSDS011(int16_t pinRX, int16_t pinTX) : _serial(pinRX, pinTX)
CjkSDS011::CjkSDS011(int16_t pinRX, int16_t pinTX)
{
_sws = ! ( pinRX < 0 || pinRX == 3 );
_pm2_5 = NAN;
@@ -35,43 +35,131 @@ CjkSDS011::CjkSDS011(int16_t pinRX, int16_t pinTX) : _serial(pinRX, pinTX)
_pm10_avr = 0;
_avr = 0;
_data.SetPacketLength(10);
_command.SetPacketLength(19);
_working_period = -1;
_sleepmode_active = false;
_serial = new ESPeasySoftwareSerial(pinRX, pinTX);
_serial->begin(9600);
}
_serial.begin(9600);
CjkSDS011::~CjkSDS011() {
delete _serial;
}
void CjkSDS011::SendCommand(byte byte1, byte byte2, byte byte3) {
_command[0] = 0xAA; // Head
_command[1] = 0xB4; // Command ID
_command[2] = byte1; // Data Byte 1
_command[3] = byte2; // Data Byte 2
_command[4] = byte3; // Data Byte 3
_command[5] = 0; // Data Byte 4
_command[6] = 0; // Data Byte 5
_command[7] = 0; // Data Byte 6
_command[8] = 0; // Data Byte 7
_command[9] = 0; // Data Byte 8
_command[10] = 0; // Data Byte 9
_command[11] = 0; // Data Byte 10
_command[12] = 0; // Data Byte 11
_command[13] = 0; // Data Byte 12
_command[14] = 0; // Data Byte 13
_command[15] = 0xFF; // Device ID byte 1, FF: All sensor response
_command[16] = 0xFF; // Device ID byte 2, FF: All sensor response
byte checksum = 0;
for (byte i=2; i< 17; ++i) {
checksum += _command[i];
}
_command[17] = checksum; // Checksum
_command[18] = 0xAB; // Tail
for (int i = 0; i < 19; ++i) {
_serial->write(_command[i]);
}
}
void CjkSDS011::SetSleepMode(bool enabled) {
byte databyte3 = enabled ? 0 : 1;
SendCommand(6, 1, databyte3);
}
void CjkSDS011::SetWorkingPeriod(int minutes) {
// Data byte 1: 8
// Data byte 2: 0: query the current mode
// 1: set mode
// Data byte 3: 0continuous(default)
// 1-30minutework 30 seconds and sleep n*60-30 seconds
if (minutes < 0 || minutes > 30) return;
// Working period is stored in the flash of the sensor. Only write to change.
const int currentWorkingPeriod = GetWorkingPeriod();
if (minutes != currentWorkingPeriod)
SendCommand(8, 1, minutes);
}
int CjkSDS011::GetWorkingPeriod() {
// Data byte 1: 8
// Data byte 2: 0: query the current mode
// 1: set mode
// Data byte 3: 0continuous(default)
// 1-30minutework 30 seconds and sleep n*60-30 seconds
SendCommand(8, 0, 0);
Process();
return _working_period;
}
void CjkSDS011::ParseCommandReply() {
switch(_data[2]) {
case 6: // Enable/Disable sleep mode.
if (_data[3] == 0)
_sleepmode_active = _data[4];
break;
case 8: // Set/Get working period
if (_data[3] == 0)
_working_period = _data[4];
break;
default:
// Not implemented.
break;
}
}
void CjkSDS011::Process()
{
while (_serial.available())
while (_serial->available())
{
_data.AddData(_serial.read());
_data.AddData(_serial->read());
if (_data[0] == 0xAA && _data[9] == 0xAB && (_data[1] == 0xC0 || _data[1] == 0xCF)) // correct packet frame?
if (_data[0] == 0xAA && _data[9] == 0xAB) // correct packet frame?
{
byte checksum = 0;
for (byte i=2; i<= 7; i++)
checksum += _data[i];
checksum += _data[i];
if (checksum != _data[8])
continue;
if (_data[1] == 0xC0) // SDS011 or SDS018?
{
_pm2_5 = (float)((_data[3] << 8) | _data[2]) * 0.1;
_pm10_ = (float)((_data[5] << 8) | _data[4]) * 0.1;
_available = true;
switch(_data[1]) {
case 0xC0: // SDS011 or SDS018?
_pm2_5 = (float)((_data[3] << 8) | _data[2]) * 0.1;
_pm10_ = (float)((_data[5] << 8) | _data[4]) * 0.1;
_available = true;
break;
case 0xCF: // SDS198?
_pm2_5 = (float)((_data[5] << 8) | _data[4]);
_pm10_ = (float)((_data[3] << 8) | _data[2]);
_available = true;
break;
case 0xC5: // Reply on command ID 0xB4
ParseCommandReply();
break;
default:
break;
}
else if (_data[1] == 0xCF) // SDS198?
{
_pm2_5 = (float)((_data[5] << 8) | _data[4]);
_pm10_ = (float)((_data[3] << 8) | _data[2]);
_available = true;
if (_available) {
_pm2_5avr += _pm2_5;
_pm10_avr += _pm10_;
_avr++;
_data.Clear();
return;
}
else
continue;
_pm2_5avr += _pm2_5;
_pm10_avr += _pm10_;
_avr++;
return;
}
}
}
@@ -83,7 +171,7 @@ boolean CjkSDS011::available()
return ret;
}
void CjkSDS011::ReadAverage(float &pm25, float &pm10)
boolean CjkSDS011::ReadAverage(float &pm25, float &pm10)
{
if (_avr)
{
@@ -92,10 +180,9 @@ void CjkSDS011::ReadAverage(float &pm25, float &pm10)
_pm2_5avr = 0;
_pm10_avr = 0;
_avr = 0;
return true;
}
else
{
pm25 = NAN;
pm10 = NAN;
}
pm25 = NAN;
pm10 = NAN;
return false;
}
+24 -3
View File
@@ -27,13 +27,15 @@
#define _jkSDS011_H_
#include "Arduino.h"
#include "SensorSerial.h"
//#include "SensorSerial.h"
#include "SensorSerialBuffer.h"
#include "ESPeasySoftwareSerial.h"
class CjkSDS011
{
public:
CjkSDS011(int16_t pinRX, int16_t pinTX);
virtual ~CjkSDS011();
void Process();
@@ -42,11 +44,28 @@ public:
float GetPM2_5() { return _pm2_5; };
float GetPM10_() { return _pm10_; };
void ReadAverage(float &pm25, float &pm10);
// Return true when there are valid samples.
boolean ReadAverage(float &pm25, float &pm10);
void SetSleepMode(bool enabled);
// Set interval to get new data, 0 .. 30 minutes.
// Minutes = 0 => continous mode.
// The setting is still effective after power off(factory default is continuous measurement)
void SetWorkingPeriod(int minutes);
// Get the working period in minutes (0 = continuous reading)
// Negative return value indicates error during communication.
int GetWorkingPeriod();
private:
SensorSerial _serial;
void SendCommand(byte byte1, byte byte2, byte byte3);
void ParseCommandReply();
// SensorSerial _serial;
ESPeasySoftwareSerial *_serial;
CSensorSerialBuffer _data;
CSensorSerialBuffer _command;
float _pm2_5;
float _pm10_;
float _pm2_5avr;
@@ -54,6 +73,8 @@ private:
uint16_t _avr;
boolean _available;
boolean _sws;
int _working_period;
boolean _sleepmode_active;
};
#endif
@@ -0,0 +1,483 @@
/**The MIT License (MIT)
Copyright (c) 2015 by Daniel Eichhorn
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
See more at http://blog.squix.ch
*/
// OLED library version >= 3.0.0
// Created by http://oleddisplay.squix.ch/ Consider a donation
// In case of problems make sure that you are using the font file with the correct version!
const char Dialog_plain_12[] PROGMEM = {
0x0D, // Width: 13
0x0F, // Height: 15
0x20, // First Char: 32
0xE0, // Numbers of Chars: 224
// Jump Table:
0xFF, 0xFF, 0x00, 0x04, // 32:65535
0x00, 0x00, 0x06, 0x05, // 33:0
0x00, 0x06, 0x07, 0x05, // 34:6
0x00, 0x0D, 0x11, 0x0A, // 35:13
0x00, 0x1E, 0x0E, 0x08, // 36:30
0x00, 0x2C, 0x16, 0x0C, // 37:44
0x00, 0x42, 0x12, 0x09, // 38:66
0x00, 0x54, 0x03, 0x03, // 39:84
0x00, 0x57, 0x06, 0x05, // 40:87
0x00, 0x5D, 0x08, 0x05, // 41:93
0x00, 0x65, 0x0B, 0x07, // 42:101
0x00, 0x70, 0x12, 0x0A, // 43:112
0x00, 0x82, 0x04, 0x03, // 44:130
0x00, 0x86, 0x08, 0x05, // 45:134
0x00, 0x8E, 0x04, 0x03, // 46:142
0x00, 0x92, 0x07, 0x04, // 47:146
0x00, 0x99, 0x0E, 0x08, // 48:153
0x00, 0xA7, 0x0C, 0x07, // 49:167
0x00, 0xB3, 0x0C, 0x07, // 50:179
0x00, 0xBF, 0x0C, 0x07, // 51:191
0x00, 0xCB, 0x0E, 0x08, // 52:203
0x00, 0xD9, 0x0C, 0x07, // 53:217
0x00, 0xE5, 0x0E, 0x08, // 54:229
0x00, 0xF3, 0x0D, 0x08, // 55:243
0x01, 0x00, 0x0E, 0x08, // 56:256
0x01, 0x0E, 0x0E, 0x08, // 57:270
0x01, 0x1C, 0x04, 0x03, // 58:284
0x01, 0x20, 0x04, 0x03, // 59:288
0x01, 0x24, 0x12, 0x0A, // 60:292
0x01, 0x36, 0x12, 0x0A, // 61:310
0x01, 0x48, 0x12, 0x0A, // 62:328
0x01, 0x5A, 0x09, 0x06, // 63:346
0x01, 0x63, 0x16, 0x0C, // 64:355
0x01, 0x79, 0x10, 0x08, // 65:377
0x01, 0x89, 0x0E, 0x08, // 66:393
0x01, 0x97, 0x10, 0x09, // 67:407
0x01, 0xA7, 0x10, 0x09, // 68:423
0x01, 0xB7, 0x0C, 0x07, // 69:439
0x01, 0xC3, 0x0B, 0x07, // 70:451
0x01, 0xCE, 0x12, 0x0A, // 71:462
0x01, 0xE0, 0x10, 0x09, // 72:480
0x01, 0xF0, 0x04, 0x03, // 73:496
0x01, 0xF4, 0x04, 0x03, // 74:500
0x01, 0xF8, 0x0E, 0x08, // 75:504
0x02, 0x06, 0x0C, 0x06, // 76:518
0x02, 0x12, 0x12, 0x0A, // 77:530
0x02, 0x24, 0x10, 0x09, // 78:548
0x02, 0x34, 0x12, 0x0A, // 79:564
0x02, 0x46, 0x0D, 0x08, // 80:582
0x02, 0x53, 0x12, 0x0A, // 81:595
0x02, 0x65, 0x10, 0x09, // 82:613
0x02, 0x75, 0x0E, 0x08, // 83:629
0x02, 0x83, 0x0D, 0x07, // 84:643
0x02, 0x90, 0x10, 0x09, // 85:656
0x02, 0xA0, 0x0F, 0x08, // 86:672
0x02, 0xAF, 0x15, 0x0C, // 87:687
0x02, 0xC4, 0x10, 0x08, // 88:708
0x02, 0xD4, 0x0D, 0x07, // 89:724
0x02, 0xE1, 0x10, 0x09, // 90:737
0x02, 0xF1, 0x06, 0x05, // 91:753
0x02, 0xF7, 0x08, 0x04, // 92:759
0x02, 0xFF, 0x08, 0x05, // 93:767
0x03, 0x07, 0x11, 0x0A, // 94:775
0x03, 0x18, 0x0C, 0x06, // 95:792
0x03, 0x24, 0x05, 0x06, // 96:804
0x03, 0x29, 0x0E, 0x08, // 97:809
0x03, 0x37, 0x0E, 0x08, // 98:823
0x03, 0x45, 0x0C, 0x07, // 99:837
0x03, 0x51, 0x0E, 0x08, // 100:849
0x03, 0x5F, 0x0E, 0x08, // 101:863
0x03, 0x6D, 0x07, 0x04, // 102:877
0x03, 0x74, 0x0E, 0x08, // 103:884
0x03, 0x82, 0x0C, 0x07, // 104:898
0x03, 0x8E, 0x04, 0x03, // 105:910
0x03, 0x92, 0x04, 0x03, // 106:914
0x03, 0x96, 0x0C, 0x07, // 107:918
0x03, 0xA2, 0x04, 0x03, // 108:930
0x03, 0xA6, 0x14, 0x0B, // 109:934
0x03, 0xBA, 0x0C, 0x07, // 110:954
0x03, 0xC6, 0x0E, 0x08, // 111:966
0x03, 0xD4, 0x0E, 0x08, // 112:980
0x03, 0xE2, 0x0E, 0x08, // 113:994
0x03, 0xF0, 0x09, 0x05, // 114:1008
0x03, 0xF9, 0x0C, 0x07, // 115:1017
0x04, 0x05, 0x08, 0x05, // 116:1029
0x04, 0x0D, 0x0C, 0x07, // 117:1037
0x04, 0x19, 0x0D, 0x07, // 118:1049
0x04, 0x26, 0x11, 0x0A, // 119:1062
0x04, 0x37, 0x0C, 0x07, // 120:1079
0x04, 0x43, 0x0D, 0x07, // 121:1091
0x04, 0x50, 0x0E, 0x07, // 122:1104
0x04, 0x5E, 0x0C, 0x07, // 123:1118
0x04, 0x6A, 0x06, 0x05, // 124:1130
0x04, 0x70, 0x0B, 0x07, // 125:1136
0x04, 0x7B, 0x11, 0x0A, // 126:1147
0x04, 0x8C, 0x0C, 0x07, // 127:1164
0x04, 0x98, 0x0C, 0x07, // 128:1176
0x04, 0xA4, 0x0C, 0x07, // 129:1188
0x04, 0xB0, 0x0C, 0x07, // 130:1200
0x04, 0xBC, 0x0C, 0x07, // 131:1212
0x04, 0xC8, 0x0C, 0x07, // 132:1224
0x04, 0xD4, 0x0C, 0x07, // 133:1236
0x04, 0xE0, 0x0C, 0x07, // 134:1248
0x04, 0xEC, 0x0C, 0x07, // 135:1260
0x04, 0xF8, 0x0C, 0x07, // 136:1272
0x05, 0x04, 0x0C, 0x07, // 137:1284
0x05, 0x10, 0x0C, 0x07, // 138:1296
0x05, 0x1C, 0x0C, 0x07, // 139:1308
0x05, 0x28, 0x0C, 0x07, // 140:1320
0x05, 0x34, 0x0C, 0x07, // 141:1332
0x05, 0x40, 0x0C, 0x07, // 142:1344
0x05, 0x4C, 0x0C, 0x07, // 143:1356
0x05, 0x58, 0x0C, 0x07, // 144:1368
0x05, 0x64, 0x0C, 0x07, // 145:1380
0x05, 0x70, 0x0C, 0x07, // 146:1392
0x05, 0x7C, 0x0C, 0x07, // 147:1404
0x05, 0x88, 0x0C, 0x07, // 148:1416
0x05, 0x94, 0x0C, 0x07, // 149:1428
0x05, 0xA0, 0x0C, 0x07, // 150:1440
0x05, 0xAC, 0x0C, 0x07, // 151:1452
0x05, 0xB8, 0x0C, 0x07, // 152:1464
0x05, 0xC4, 0x0C, 0x07, // 153:1476
0x05, 0xD0, 0x0C, 0x07, // 154:1488
0x05, 0xDC, 0x0C, 0x07, // 155:1500
0x05, 0xE8, 0x0C, 0x07, // 156:1512
0x05, 0xF4, 0x0C, 0x07, // 157:1524
0x06, 0x00, 0x0C, 0x07, // 158:1536
0x06, 0x0C, 0x0C, 0x07, // 159:1548
0xFF, 0xFF, 0x00, 0x04, // 160:65535
0x06, 0x18, 0x06, 0x05, // 161:1560
0x06, 0x1E, 0x0E, 0x08, // 162:1566
0x06, 0x2C, 0x0E, 0x08, // 163:1580
0x06, 0x3A, 0x0C, 0x07, // 164:1594
0x06, 0x46, 0x0C, 0x07, // 165:1606
0x06, 0x52, 0x06, 0x05, // 166:1618
0x06, 0x58, 0x0C, 0x07, // 167:1624
0x06, 0x64, 0x07, 0x05, // 168:1636
0x06, 0x6B, 0x16, 0x0D, // 169:1643
0x06, 0x81, 0x0A, 0x06, // 170:1665
0x06, 0x8B, 0x0E, 0x08, // 171:1675
0x06, 0x99, 0x12, 0x0A, // 172:1689
0x06, 0xAB, 0x08, 0x05, // 173:1707
0x06, 0xB3, 0x16, 0x0D, // 174:1715
0x06, 0xC9, 0x09, 0x06, // 175:1737
0x06, 0xD2, 0x09, 0x06, // 176:1746
0x06, 0xDB, 0x12, 0x0A, // 177:1755
0x06, 0xED, 0x08, 0x05, // 178:1773
0x06, 0xF5, 0x07, 0x05, // 179:1781
0x06, 0xFC, 0x09, 0x06, // 180:1788
0x07, 0x05, 0x0E, 0x07, // 181:1797
0x07, 0x13, 0x0C, 0x07, // 182:1811
0x07, 0x1F, 0x03, 0x03, // 183:1823
0x07, 0x22, 0x08, 0x06, // 184:1826
0x07, 0x2A, 0x07, 0x05, // 185:1834
0x07, 0x31, 0x0C, 0x07, // 186:1841
0x07, 0x3D, 0x0E, 0x07, // 187:1853
0x07, 0x4B, 0x16, 0x0B, // 188:1867
0x07, 0x61, 0x16, 0x0C, // 189:1889
0x07, 0x77, 0x16, 0x0B, // 190:1911
0x07, 0x8D, 0x0A, 0x06, // 191:1933
0x07, 0x97, 0x10, 0x08, // 192:1943
0x07, 0xA7, 0x10, 0x08, // 193:1959
0x07, 0xB7, 0x10, 0x08, // 194:1975
0x07, 0xC7, 0x10, 0x08, // 195:1991
0x07, 0xD7, 0x0E, 0x07, // 196:2007
0x07, 0xE5, 0x0E, 0x07, // 197:2021
0x07, 0xF3, 0x14, 0x0B, // 198:2035
0x08, 0x07, 0x10, 0x09, // 199:2055
0x08, 0x17, 0x0C, 0x07, // 200:2071
0x08, 0x23, 0x0C, 0x07, // 201:2083
0x08, 0x2F, 0x0C, 0x07, // 202:2095
0x08, 0x3B, 0x0C, 0x07, // 203:2107
0x08, 0x47, 0x04, 0x03, // 204:2119
0x08, 0x4B, 0x05, 0x03, // 205:2123
0x08, 0x50, 0x05, 0x03, // 206:2128
0x08, 0x55, 0x07, 0x05, // 207:2133
0x08, 0x5C, 0x10, 0x09, // 208:2140
0x08, 0x6C, 0x10, 0x09, // 209:2156
0x08, 0x7C, 0x12, 0x0A, // 210:2172
0x08, 0x8E, 0x12, 0x0A, // 211:2190
0x08, 0xA0, 0x12, 0x0A, // 212:2208
0x08, 0xB2, 0x12, 0x0A, // 213:2226
0x08, 0xC4, 0x12, 0x0A, // 214:2244
0x08, 0xD6, 0x10, 0x0A, // 215:2262
0x08, 0xE6, 0x12, 0x0A, // 216:2278
0x08, 0xF8, 0x10, 0x09, // 217:2296
0x09, 0x08, 0x10, 0x09, // 218:2312
0x09, 0x18, 0x10, 0x09, // 219:2328
0x09, 0x28, 0x10, 0x09, // 220:2344
0x09, 0x38, 0x0D, 0x07, // 221:2360
0x09, 0x45, 0x0E, 0x08, // 222:2373
0x09, 0x53, 0x0E, 0x08, // 223:2387
0x09, 0x61, 0x0E, 0x08, // 224:2401
0x09, 0x6F, 0x0E, 0x08, // 225:2415
0x09, 0x7D, 0x0E, 0x08, // 226:2429
0x09, 0x8B, 0x0E, 0x08, // 227:2443
0x09, 0x99, 0x0E, 0x08, // 228:2457
0x09, 0xA7, 0x0E, 0x08, // 229:2471
0x09, 0xB5, 0x16, 0x0C, // 230:2485
0x09, 0xCB, 0x0C, 0x07, // 231:2507
0x09, 0xD7, 0x0E, 0x08, // 232:2519
0x09, 0xE5, 0x0E, 0x08, // 233:2533
0x09, 0xF3, 0x0E, 0x08, // 234:2547
0x0A, 0x01, 0x0E, 0x08, // 235:2561
0x0A, 0x0F, 0x04, 0x03, // 236:2575
0x0A, 0x13, 0x05, 0x03, // 237:2579
0x0A, 0x18, 0x05, 0x03, // 238:2584
0x0A, 0x1D, 0x05, 0x03, // 239:2589
0x0A, 0x22, 0x0E, 0x08, // 240:2594
0x0A, 0x30, 0x0C, 0x07, // 241:2608
0x0A, 0x3C, 0x0E, 0x08, // 242:2620
0x0A, 0x4A, 0x0E, 0x08, // 243:2634
0x0A, 0x58, 0x0E, 0x08, // 244:2648
0x0A, 0x66, 0x0E, 0x08, // 245:2662
0x0A, 0x74, 0x0E, 0x08, // 246:2676
0x0A, 0x82, 0x11, 0x0A, // 247:2690
0x0A, 0x93, 0x0E, 0x08, // 248:2707
0x0A, 0xA1, 0x0C, 0x07, // 249:2721
0x0A, 0xAD, 0x0C, 0x07, // 250:2733
0x0A, 0xB9, 0x0C, 0x07, // 251:2745
0x0A, 0xC5, 0x0C, 0x07, // 252:2757
0x0A, 0xD1, 0x0D, 0x07, // 253:2769
0x0A, 0xDE, 0x0E, 0x08, // 254:2782
0x0A, 0xEC, 0x0B, 0x07, // 255:2796
// Font Data:
0x00,0x00,0x00,0x00,0xF8,0x09, // 33
0x00,0x00,0x38,0x00,0x00,0x00,0x38, // 34
0x00,0x00,0x00,0x01,0x40,0x0D,0xC0,0x03,0x78,0x01,0x40,0x0F,0xE0,0x01,0x58,0x01,0x40, // 35
0x00,0x00,0x70,0x08,0xC8,0x08,0xFC,0x1F,0x88,0x08,0x88,0x0D,0x18,0x07, // 36
0x00,0x00,0x70,0x00,0x88,0x00,0x88,0x08,0x70,0x06,0x80,0x01,0x40,0x00,0x30,0x07,0x88,0x08,0x80,0x08,0x00,0x07, // 37
0x00,0x00,0x80,0x07,0xF0,0x0C,0x48,0x08,0x88,0x09,0x08,0x0B,0x00,0x06,0x80,0x0F,0x80,0x08, // 38
0x00,0x00,0x38, // 39
0x00,0x00,0xF0,0x07,0x0C,0x18, // 40
0x00,0x00,0x00,0x00,0x1C,0x18,0xE0,0x07, // 41
0x00,0x00,0x50,0x00,0x60,0x00,0xF8,0x00,0x60,0x00,0x50, // 42
0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0xF0,0x0F,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01, // 43
0x00,0x10,0x00,0x0C, // 44
0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01, // 45
0x00,0x00,0x00,0x08, // 46
0x00,0x30,0x00,0x0F,0xE0,0x00,0x18, // 47
0x00,0x00,0xE0,0x03,0x18,0x0C,0x08,0x08,0x08,0x08,0x18,0x0C,0xE0,0x03, // 48
0x00,0x00,0x08,0x08,0x08,0x08,0xF8,0x0F,0x00,0x08,0x00,0x08, // 49
0x00,0x00,0x18,0x0C,0x08,0x0E,0x08,0x0B,0x88,0x08,0x70,0x08, // 50
0x00,0x0C,0x08,0x08,0x48,0x08,0x48,0x08,0xC8,0x0C,0xB0,0x07, // 51
0x00,0x00,0x00,0x03,0xC0,0x02,0x60,0x02,0x18,0x02,0xF8,0x0F,0x00,0x02, // 52
0x00,0x0C,0x78,0x08,0x48,0x08,0x48,0x08,0xC8,0x0C,0x80,0x07, // 53
0x00,0x00,0xE0,0x03,0x90,0x0C,0x48,0x08,0x48,0x08,0xC8,0x0C,0x88,0x07, // 54
0x00,0x00,0x08,0x00,0x08,0x08,0x08,0x0E,0xC8,0x03,0x78,0x00,0x18, // 55
0x00,0x00,0x70,0x07,0x88,0x09,0x88,0x08,0x88,0x08,0x88,0x09,0x70,0x07, // 56
0x00,0x00,0xF0,0x08,0x98,0x09,0x08,0x09,0x08,0x09,0x98,0x04,0xE0,0x03, // 57
0x00,0x00,0x40,0x08, // 58
0x00,0x10,0x20,0x0C, // 59
0x00,0x00,0x80,0x01,0x80,0x01,0x80,0x03,0x40,0x02,0x40,0x02,0x60,0x04,0x20,0x04,0x20,0x04, // 60
0x00,0x00,0x40,0x02,0x40,0x02,0x40,0x02,0x40,0x02,0x40,0x02,0x40,0x02,0x40,0x02,0x40,0x02, // 61
0x00,0x00,0x20,0x04,0x20,0x04,0x40,0x02,0x40,0x02,0xC0,0x02,0x80,0x01,0x80,0x01,0x00,0x01, // 62
0x00,0x00,0x08,0x00,0x88,0x0B,0xC8,0x00,0x70, // 63
0x00,0x00,0xC0,0x07,0x20,0x08,0x10,0x10,0x88,0x23,0x48,0x24,0x48,0x24,0x48,0x24,0xD0,0x17,0x30,0x04,0xC0,0x03, // 64
0x00,0x08,0x00,0x0F,0xE0,0x03,0x38,0x02,0x18,0x02,0xE0,0x02,0x00,0x07,0x00,0x0C, // 65
0x00,0x00,0xF8,0x0F,0x88,0x08,0x88,0x08,0x88,0x08,0x88,0x08,0x70,0x07, // 66
0x00,0x00,0xE0,0x03,0x10,0x04,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x04, // 67
0x00,0x00,0xF8,0x0F,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x04,0xE0,0x03, // 68
0x00,0x00,0xF8,0x0F,0x88,0x08,0x88,0x08,0x88,0x08,0x88,0x08, // 69
0x00,0x00,0xF8,0x0F,0x88,0x00,0x88,0x00,0x88,0x00,0x08, // 70
0x00,0x00,0xE0,0x03,0x10,0x04,0x08,0x08,0x08,0x08,0x08,0x08,0x88,0x08,0x88,0x08,0x90,0x07, // 71
0x00,0x00,0xF8,0x0F,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xF8,0x0F, // 72
0x00,0x00,0xF8,0x0F, // 73
0x00,0x40,0xF8,0x3F, // 74
0x00,0x00,0xF8,0x0F,0xC0,0x00,0x60,0x01,0x30,0x02,0x18,0x04,0x08,0x08, // 75
0x00,0x00,0xF8,0x0F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08, // 76
0x00,0x00,0xF8,0x0F,0x18,0x00,0xE0,0x00,0x00,0x03,0x00,0x03,0xE0,0x00,0x18,0x00,0xF8,0x0F, // 77
0x00,0x00,0xF8,0x0F,0x18,0x00,0x60,0x00,0xC0,0x01,0x00,0x03,0x00,0x0C,0xF8,0x0F, // 78
0x00,0x00,0xE0,0x03,0x10,0x04,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x04,0xE0,0x03, // 79
0x00,0x00,0xF8,0x0F,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x70, // 80
0x00,0x00,0xE0,0x03,0x10,0x04,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x18,0x10,0x24,0xE0,0x03, // 81
0x00,0x00,0xF8,0x0F,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x01,0x70,0x07,0x00,0x0C, // 82
0x00,0x00,0x70,0x0C,0xC8,0x08,0x88,0x08,0x88,0x08,0x88,0x08,0x18,0x07, // 83
0x08,0x00,0x08,0x00,0x08,0x00,0xF8,0x0F,0x08,0x00,0x08,0x00,0x08, // 84
0x00,0x00,0xF8,0x07,0x00,0x0C,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x0C,0xF8,0x07, // 85
0x08,0x00,0x78,0x00,0xC0,0x01,0x00,0x0E,0x00,0x0E,0x80,0x03,0x70,0x00,0x18, // 86
0x00,0x00,0xF8,0x00,0x80,0x0F,0x00,0x0C,0xC0,0x03,0x38,0x00,0x78,0x00,0x80,0x07,0x00,0x0C,0xC0,0x07,0x78, // 87
0x00,0x00,0x08,0x0C,0x30,0x06,0xE0,0x01,0xC0,0x01,0x30,0x03,0x18,0x0C,0x00,0x08, // 88
0x08,0x00,0x10,0x00,0x60,0x00,0x80,0x0F,0x60,0x00,0x18,0x00,0x08, // 89
0x00,0x00,0x08,0x0C,0x08,0x0E,0x08,0x0B,0x88,0x08,0x68,0x08,0x38,0x08,0x18,0x08, // 90
0x00,0x00,0xFC,0x1F,0x04,0x10, // 91
0x18,0x00,0xE0,0x00,0x00,0x0F,0x00,0x30, // 92
0x00,0x00,0x00,0x00,0x04,0x10,0xFC,0x1F, // 93
0x00,0x00,0x40,0x00,0x20,0x00,0x30,0x00,0x18,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40, // 94
0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40, // 95
0x00,0x00,0x02,0x00,0x0C, // 96
0x00,0x00,0x60,0x06,0x20,0x09,0x20,0x09,0x20,0x09,0x60,0x05,0xC0,0x0F, // 97
0x00,0x00,0xFC,0x0F,0x40,0x04,0x20,0x08,0x20,0x08,0x60,0x0C,0xC0,0x07, // 98
0x00,0x00,0xC0,0x07,0x60,0x0C,0x20,0x08,0x20,0x08,0x20,0x08, // 99
0x00,0x00,0xC0,0x07,0x60,0x0C,0x20,0x08,0x20,0x08,0x40,0x04,0xFC,0x0F, // 100
0x00,0x00,0xC0,0x07,0x60,0x0D,0x20,0x09,0x20,0x09,0x60,0x09,0xC0,0x09, // 101
0x20,0x00,0xF8,0x0F,0x24,0x00,0x24, // 102
0x00,0x00,0xC0,0x07,0x60,0x4C,0x20,0x48,0x20,0x48,0x40,0x64,0xE0,0x3F, // 103
0x00,0x00,0xFC,0x0F,0x40,0x00,0x20,0x00,0x20,0x00,0xC0,0x0F, // 104
0x00,0x00,0xE4,0x0F, // 105
0x00,0x40,0xE4,0x3F, // 106
0x00,0x00,0xFC,0x0F,0x00,0x01,0x80,0x02,0x40,0x04,0x20,0x08, // 107
0x00,0x00,0xFC,0x0F, // 108
0x00,0x00,0xE0,0x0F,0x40,0x00,0x20,0x00,0x20,0x00,0xC0,0x0F,0x40,0x00,0x20,0x00,0x20,0x00,0xC0,0x0F, // 109
0x00,0x00,0xE0,0x0F,0x40,0x00,0x20,0x00,0x20,0x00,0xC0,0x0F, // 110
0x00,0x00,0xC0,0x07,0x60,0x0C,0x20,0x08,0x20,0x08,0x60,0x0C,0xC0,0x07, // 111
0x00,0x00,0xE0,0x7F,0x40,0x04,0x20,0x08,0x20,0x08,0x60,0x0C,0xC0,0x07, // 112
0x00,0x00,0xC0,0x07,0x60,0x0C,0x20,0x08,0x20,0x08,0x40,0x04,0xE0,0x7F, // 113
0x00,0x00,0xE0,0x0F,0x40,0x00,0x20,0x00,0x20, // 114
0x00,0x00,0xC0,0x08,0x20,0x09,0x20,0x09,0x20,0x09,0x20,0x06, // 115
0x20,0x00,0xF8,0x0F,0x20,0x08,0x20,0x08, // 116
0x00,0x00,0xE0,0x07,0x00,0x08,0x00,0x08,0x00,0x04,0xE0,0x0F, // 117
0x00,0x00,0xE0,0x00,0x00,0x07,0x00,0x08,0x00,0x07,0xE0,0x01,0x20, // 118
0x00,0x00,0xE0,0x01,0x00,0x0E,0x00,0x0F,0xE0,0x00,0xE0,0x01,0x00,0x0E,0x00,0x0F,0xE0, // 119
0x00,0x00,0x20,0x0C,0xC0,0x06,0x80,0x01,0xC0,0x06,0x60,0x0C, // 120
0x00,0x00,0xE0,0x40,0x00,0x67,0x00,0x38,0x00,0x07,0xE0,0x00,0x20, // 121
0x00,0x00,0x20,0x0C,0x20,0x0E,0x20,0x0B,0xA0,0x08,0x60,0x08,0x20,0x08, // 122
0x00,0x00,0x80,0x00,0x80,0x00,0x7C,0x3F,0x04,0x20,0x04,0x20, // 123
0x00,0x00,0x00,0x00,0xFC,0x3F, // 124
0x00,0x00,0x04,0x20,0x04,0x20,0x7C,0x3F,0x80,0x00,0x80, // 125
0x00,0x00,0x00,0x01,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x80, // 126
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 127
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 128
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 129
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 130
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 131
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 132
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 133
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 134
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 135
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 136
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 137
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 138
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 139
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 140
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 141
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 142
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 143
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 144
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 145
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 146
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 147
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 148
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 149
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 150
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 151
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 152
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 153
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 154
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 155
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 156
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 157
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 158
0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x3F, // 159
0x00,0x00,0x00,0x00,0xC8,0x0F, // 161
0x00,0x00,0xC0,0x07,0x60,0x0C,0x20,0x08,0xF0,0x3F,0x20,0x08,0x20,0x08, // 162
0x00,0x00,0x80,0x08,0xF0,0x0F,0x88,0x08,0x88,0x08,0x88,0x08,0x08,0x08, // 163
0x00,0x00,0xC0,0x07,0x40,0x04,0x40,0x04,0x40,0x04,0xC0,0x07, // 164
0x00,0x00,0x58,0x01,0x60,0x01,0x80,0x0F,0x60,0x01,0x58,0x01, // 165
0x00,0x00,0x00,0x00,0x78,0x3C, // 166
0x00,0x00,0xB0,0x21,0x48,0x22,0x48,0x24,0x88,0x1C,0x00,0x03, // 167
0x00,0x00,0x04,0x00,0x00,0x00,0x04, // 168
0x00,0x00,0x00,0x00,0xE0,0x03,0x30,0x06,0xD8,0x0D,0x28,0x0A,0x28,0x0A,0x28,0x0A,0x18,0x0C,0x30,0x06,0xE0,0x03, // 169
0x00,0x00,0xE8,0x02,0xA8,0x02,0xA8,0x02,0xF0,0x02, // 170
0x00,0x00,0x00,0x01,0x80,0x02,0x40,0x05,0x80,0x01,0xC0,0x02,0x40,0x04, // 171
0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x07, // 172
0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01, // 173
0x00,0x00,0x00,0x00,0xE0,0x03,0x30,0x06,0x18,0x0C,0xE8,0x0B,0xA8,0x08,0x68,0x0B,0x18,0x0C,0x30,0x06,0xE0,0x03, // 174
0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04, // 175
0x00,0x00,0x30,0x00,0x48,0x00,0x48,0x00,0x30, // 176
0x00,0x00,0x80,0x08,0x80,0x08,0x80,0x08,0xF0,0x0B,0x80,0x08,0x80,0x08,0x80,0x08,0x80,0x08, // 177
0x08,0x01,0x88,0x01,0x48,0x01,0x38,0x01, // 178
0x08,0x01,0x28,0x01,0x28,0x01,0xD8, // 179
0x00,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x02, // 180
0x00,0x00,0xE0,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0xE0,0x0F,0x00,0x08, // 181
0x20,0x00,0xF0,0x00,0xF8,0x00,0xF8,0x3F,0x08,0x00,0xF8,0x3F, // 182
0x00,0x00,0x80, // 183
0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x60, // 184
0x00,0x00,0x88,0x00,0xF8,0x00,0x80, // 185
0x00,0x00,0x70,0x02,0x88,0x02,0x88,0x02,0x88,0x02,0x70,0x02, // 186
0x00,0x00,0x40,0x06,0x80,0x02,0x40,0x05,0xC0,0x02,0x80,0x01,0x00,0x01, // 187
0x00,0x00,0x88,0x00,0xF8,0x00,0x80,0x0C,0x00,0x03,0x80,0x00,0x60,0x00,0x18,0x07,0x00,0x05,0x80,0x0F,0x00,0x04, // 188
0x00,0x00,0x88,0x00,0xF8,0x00,0x80,0x08,0x00,0x06,0x80,0x01,0x40,0x00,0xB0,0x08,0x88,0x0C,0x80,0x0A,0x80,0x09, // 189
0x88,0x00,0xA8,0x00,0xA8,0x00,0xD8,0x0C,0x00,0x03,0xC0,0x00,0x20,0x00,0x18,0x07,0x80,0x04,0x80,0x0F,0x00,0x04, // 190
0x00,0x00,0x00,0x07,0x80,0x09,0xE8,0x08,0x00,0x08, // 191
0x00,0x08,0x00,0x0F,0xE0,0x03,0x39,0x02,0x1A,0x02,0xE0,0x02,0x00,0x07,0x00,0x0C, // 192
0x00,0x08,0x00,0x0F,0xE0,0x03,0x38,0x02,0x1B,0x02,0xE1,0x02,0x00,0x07,0x00,0x0C, // 193
0x00,0x08,0x00,0x0F,0xE0,0x03,0x3A,0x02,0x1B,0x02,0xE0,0x02,0x00,0x07,0x00,0x0C, // 194
0x00,0x08,0x00,0x0F,0xE3,0x03,0x39,0x02,0x1A,0x02,0xE3,0x02,0x00,0x07,0x00,0x0C, // 195
0x00,0x0C,0x80,0x07,0xF2,0x02,0x08,0x02,0xF2,0x02,0x80,0x07,0x00,0x0C, // 196
0x00,0x0C,0x80,0x03,0x77,0x02,0x19,0x02,0x66,0x02,0x80,0x03,0x00,0x0C, // 197
0x00,0x0C,0x00,0x07,0xE0,0x03,0x38,0x02,0x08,0x02,0xF8,0x0F,0x88,0x08,0x88,0x08,0x88,0x08,0x88,0x08, // 198
0x00,0x00,0xE0,0x03,0x10,0x06,0x08,0x0C,0x08,0x4C,0x08,0x7C,0x08,0x0C,0x10,0x04, // 199
0x00,0x00,0xF8,0x0F,0x89,0x08,0x8A,0x08,0x88,0x08,0x88,0x08, // 200
0x00,0x00,0xF8,0x0F,0x88,0x08,0x8A,0x08,0x89,0x08,0x88,0x08, // 201
0x00,0x00,0xF8,0x0F,0x8A,0x08,0x89,0x08,0x8A,0x08,0x88,0x08, // 202
0x00,0x00,0xF8,0x0F,0x8A,0x08,0x88,0x08,0x8A,0x08,0x88,0x08, // 203
0x01,0x00,0xFA,0x0F, // 204
0x00,0x00,0xFA,0x0F,0x01, // 205
0x02,0x00,0xF9,0x0F,0x02, // 206
0x00,0x00,0x02,0x00,0xF8,0x0F,0x02, // 207
0x80,0x00,0xF8,0x0F,0x88,0x08,0x88,0x08,0x08,0x08,0x08,0x08,0x10,0x04,0xE0,0x03, // 208
0x00,0x00,0xF8,0x0F,0x1A,0x00,0x61,0x00,0xC3,0x01,0x02,0x03,0x01,0x0C,0xF8,0x0F, // 209
0x00,0x00,0xE0,0x03,0x10,0x04,0x08,0x08,0x09,0x08,0x0A,0x08,0x08,0x08,0x10,0x04,0xE0,0x03, // 210
0x00,0x00,0xE0,0x03,0x10,0x04,0x08,0x08,0x0A,0x08,0x09,0x08,0x08,0x08,0x10,0x04,0xE0,0x03, // 211
0x00,0x00,0xE0,0x03,0x10,0x04,0x0A,0x08,0x09,0x08,0x09,0x08,0x0A,0x08,0x10,0x04,0xE0,0x03, // 212
0x00,0x00,0xE0,0x03,0x10,0x04,0x0B,0x08,0x09,0x08,0x0A,0x08,0x0B,0x08,0x10,0x04,0xE0,0x03, // 213
0x00,0x00,0xE0,0x03,0x10,0x04,0x0A,0x08,0x08,0x08,0x08,0x08,0x0A,0x08,0x10,0x04,0xE0,0x03, // 214
0x00,0x00,0x00,0x00,0x20,0x04,0x40,0x02,0x80,0x01,0x80,0x01,0x40,0x02,0x20,0x04, // 215
0x00,0x00,0xE0,0x0B,0x10,0x04,0x08,0x0B,0x88,0x09,0xC8,0x08,0x68,0x08,0x10,0x04,0xE8,0x03, // 216
0x00,0x00,0xF8,0x07,0x00,0x0C,0x01,0x08,0x02,0x08,0x00,0x08,0x00,0x0C,0xF8,0x07, // 217
0x00,0x00,0xF8,0x07,0x00,0x0C,0x00,0x08,0x02,0x08,0x01,0x08,0x00,0x0C,0xF8,0x07, // 218
0x00,0x00,0xF8,0x07,0x00,0x0C,0x03,0x08,0x01,0x08,0x03,0x08,0x00,0x0C,0xF8,0x07, // 219
0x00,0x00,0xF8,0x07,0x00,0x0C,0x02,0x08,0x00,0x08,0x02,0x08,0x00,0x0C,0xF8,0x07, // 220
0x08,0x00,0x10,0x00,0x60,0x00,0x82,0x0F,0x60,0x00,0x18,0x00,0x08, // 221
0x00,0x00,0xF8,0x0F,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0xC0,0x01, // 222
0x00,0x00,0xF8,0x0F,0x04,0x00,0xE4,0x08,0x94,0x08,0x18,0x09,0x00,0x06, // 223
0x00,0x00,0x60,0x06,0x24,0x09,0x28,0x09,0x30,0x09,0x60,0x05,0xC0,0x0F, // 224
0x00,0x00,0x60,0x06,0x20,0x09,0x30,0x09,0x28,0x09,0x64,0x05,0xC0,0x0F, // 225
0x00,0x00,0x60,0x06,0x38,0x09,0x24,0x09,0x2C,0x09,0x70,0x05,0xC0,0x0F, // 226
0x00,0x00,0x60,0x06,0x2C,0x09,0x24,0x09,0x28,0x09,0x6C,0x05,0xC0,0x0F, // 227
0x00,0x00,0x60,0x06,0x24,0x09,0x20,0x09,0x24,0x09,0x60,0x05,0xC0,0x0F, // 228
0x00,0x00,0x60,0x06,0x24,0x09,0x2A,0x09,0x2A,0x09,0x64,0x05,0xC0,0x0F, // 229
0x00,0x00,0x20,0x07,0xA0,0x08,0xA0,0x08,0xA0,0x0C,0xC0,0x07,0x60,0x0D,0x20,0x09,0x20,0x09,0x60,0x09,0xC0,0x09, // 230
0x00,0x00,0xC0,0x07,0x60,0x0C,0x20,0x4C,0x20,0x7C,0x20,0x04, // 231
0x00,0x00,0xC0,0x07,0x64,0x0D,0x2C,0x09,0x20,0x09,0x60,0x09,0xC0,0x09, // 232
0x00,0x00,0xC0,0x07,0x60,0x0D,0x20,0x09,0x2C,0x09,0x64,0x09,0xC0,0x09, // 233
0x00,0x00,0xC0,0x07,0x68,0x0D,0x24,0x09,0x24,0x09,0x68,0x09,0xC0,0x09, // 234
0x00,0x00,0xC0,0x07,0x60,0x0D,0x24,0x09,0x20,0x09,0x64,0x09,0xC0,0x09, // 235
0x04,0x00,0xF8,0x0F, // 236
0x00,0x00,0xF8,0x0F,0x04, // 237
0x08,0x00,0xE4,0x0F,0x08, // 238
0x04,0x00,0xE0,0x0F,0x04, // 239
0x00,0x00,0xC0,0x07,0x74,0x0C,0x2C,0x08,0x38,0x08,0x24,0x0C,0xC0,0x07, // 240
0x00,0x00,0xE0,0x0F,0x4C,0x00,0x2C,0x00,0x2C,0x00,0xC0,0x0F, // 241
0x00,0x00,0xC0,0x07,0x64,0x0C,0x2C,0x08,0x20,0x08,0x60,0x0C,0xC0,0x07, // 242
0x00,0x00,0xC0,0x07,0x60,0x0C,0x20,0x08,0x2C,0x08,0x64,0x0C,0xC0,0x07, // 243
0x00,0x00,0xC0,0x07,0x68,0x0C,0x24,0x08,0x24,0x08,0x68,0x0C,0xC0,0x07, // 244
0x00,0x00,0xC0,0x07,0x6C,0x0C,0x24,0x08,0x28,0x08,0x6C,0x0C,0xC0,0x07, // 245
0x00,0x00,0xC0,0x07,0x64,0x0C,0x20,0x08,0x20,0x08,0x64,0x0C,0xC0,0x07, // 246
0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xA0,0x02,0x80,0x00,0x80,0x00,0x80,0x00,0x80, // 247
0x00,0x00,0xC0,0x0F,0x60,0x0C,0x20,0x0B,0xA0,0x08,0x60,0x0C,0xE0,0x07, // 248
0x00,0x00,0xE0,0x07,0x04,0x08,0x18,0x08,0x00,0x04,0xE0,0x0F, // 249
0x00,0x00,0xE0,0x07,0x00,0x08,0x18,0x08,0x04,0x04,0xE0,0x0F, // 250
0x00,0x00,0xE0,0x07,0x18,0x08,0x04,0x08,0x18,0x04,0xE0,0x0F, // 251
0x00,0x00,0xE0,0x07,0x04,0x08,0x00,0x08,0x04,0x04,0xE0,0x0F, // 252
0x00,0x00,0xE0,0x40,0x00,0x67,0x10,0x38,0x0C,0x07,0xE4,0x01,0x20, // 253
0x00,0x00,0xFC,0x7F,0x40,0x04,0x20,0x08,0x20,0x08,0x60,0x0C,0xC0,0x07, // 254
0x00,0x00,0xE0,0x40,0x04,0x47,0x00,0x38,0x84,0x07,0xE0 // 255
};
+831
View File
@@ -0,0 +1,831 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 by Daniel Eichhorn
* Copyright (c) 2016 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/
#include "OLEDDisplay.h"
OLEDDisplay::~OLEDDisplay() {
end();
}
bool OLEDDisplay::init() {
if (!this->connect()) {
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Can't establish connection to display\n");
return false;
}
if(this->buffer==NULL) {
this->buffer = (uint8_t*) malloc(sizeof(uint8_t) * DISPLAY_BUFFER_SIZE);
if(!this->buffer) {
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Not enough memory to create display\n");
return false;
}
}
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
if(this->buffer_back==NULL) {
this->buffer_back = (uint8_t*) malloc(sizeof(uint8_t) * DISPLAY_BUFFER_SIZE);
if(!this->buffer_back) {
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Not enough memory to create back buffer\n");
free(this->buffer);
return false;
}
}
#endif
sendInitCommands();
resetDisplay();
return true;
}
void OLEDDisplay::end() {
if (this->buffer) { free(this->buffer); this->buffer = NULL; }
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
if (this->buffer_back) { free(this->buffer_back); this->buffer_back = NULL; }
#endif
if (this->logBuffer != NULL) { free(this->logBuffer); this->logBuffer = NULL; }
}
void OLEDDisplay::resetDisplay(void) {
clear();
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
memset(buffer_back, 1, DISPLAY_BUFFER_SIZE);
#endif
display();
}
void OLEDDisplay::setColor(OLEDDISPLAY_COLOR color) {
this->color = color;
}
void OLEDDisplay::setPixel(int16_t x, int16_t y) {
if (x >= 0 && x < this->width() && y >= 0 && y < this->height()) {
switch (color) {
case WHITE: buffer[x + (y / 8) * this->width()] |= (1 << (y & 7)); break;
case BLACK: buffer[x + (y / 8) * this->width()] &= ~(1 << (y & 7)); break;
case INVERSE: buffer[x + (y / 8) * this->width()] ^= (1 << (y & 7)); break;
}
}
}
// Bresenham's algorithm - thx wikipedia and Adafruit_GFX
void OLEDDisplay::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {
int16_t steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {
_swap_int16_t(x0, y0);
_swap_int16_t(x1, y1);
}
if (x0 > x1) {
_swap_int16_t(x0, x1);
_swap_int16_t(y0, y1);
}
int16_t dx, dy;
dx = x1 - x0;
dy = abs(y1 - y0);
int16_t err = dx / 2;
int16_t ystep;
if (y0 < y1) {
ystep = 1;
} else {
ystep = -1;
}
for (; x0<=x1; x0++) {
if (steep) {
setPixel(y0, x0);
} else {
setPixel(x0, y0);
}
err -= dy;
if (err < 0) {
y0 += ystep;
err += dx;
}
}
}
void OLEDDisplay::drawRect(int16_t x, int16_t y, int16_t width, int16_t height) {
drawHorizontalLine(x, y, width);
drawVerticalLine(x, y, height);
drawVerticalLine(x + width - 1, y, height);
drawHorizontalLine(x, y + height - 1, width);
}
void OLEDDisplay::fillRect(int16_t xMove, int16_t yMove, int16_t width, int16_t height) {
for (int16_t x = xMove; x < xMove + width; x++) {
drawVerticalLine(x, yMove, height);
}
}
void OLEDDisplay::drawCircle(int16_t x0, int16_t y0, int16_t radius) {
int16_t x = 0, y = radius;
int16_t dp = 1 - radius;
do {
if (dp < 0)
dp = dp + 2 * (++x) + 3;
else
dp = dp + 2 * (++x) - 2 * (--y) + 5;
setPixel(x0 + x, y0 + y); //For the 8 octants
setPixel(x0 - x, y0 + y);
setPixel(x0 + x, y0 - y);
setPixel(x0 - x, y0 - y);
setPixel(x0 + y, y0 + x);
setPixel(x0 - y, y0 + x);
setPixel(x0 + y, y0 - x);
setPixel(x0 - y, y0 - x);
} while (x < y);
setPixel(x0 + radius, y0);
setPixel(x0, y0 + radius);
setPixel(x0 - radius, y0);
setPixel(x0, y0 - radius);
}
void OLEDDisplay::drawCircleQuads(int16_t x0, int16_t y0, int16_t radius, uint8_t quads) {
int16_t x = 0, y = radius;
int16_t dp = 1 - radius;
while (x < y) {
if (dp < 0)
dp = dp + 2 * (++x) + 3;
else
dp = dp + 2 * (++x) - 2 * (--y) + 5;
if (quads & 0x1) {
setPixel(x0 + x, y0 - y);
setPixel(x0 + y, y0 - x);
}
if (quads & 0x2) {
setPixel(x0 - y, y0 - x);
setPixel(x0 - x, y0 - y);
}
if (quads & 0x4) {
setPixel(x0 - y, y0 + x);
setPixel(x0 - x, y0 + y);
}
if (quads & 0x8) {
setPixel(x0 + x, y0 + y);
setPixel(x0 + y, y0 + x);
}
}
if (quads & 0x1 && quads & 0x8) {
setPixel(x0 + radius, y0);
}
if (quads & 0x4 && quads & 0x8) {
setPixel(x0, y0 + radius);
}
if (quads & 0x2 && quads & 0x4) {
setPixel(x0 - radius, y0);
}
if (quads & 0x1 && quads & 0x2) {
setPixel(x0, y0 - radius);
}
}
void OLEDDisplay::fillCircle(int16_t x0, int16_t y0, int16_t radius) {
int16_t x = 0, y = radius;
int16_t dp = 1 - radius;
do {
if (dp < 0)
dp = dp + 2 * (++x) + 3;
else
dp = dp + 2 * (++x) - 2 * (--y) + 5;
drawHorizontalLine(x0 - x, y0 - y, 2*x);
drawHorizontalLine(x0 - x, y0 + y, 2*x);
drawHorizontalLine(x0 - y, y0 - x, 2*y);
drawHorizontalLine(x0 - y, y0 + x, 2*y);
} while (x < y);
drawHorizontalLine(x0 - radius, y0, 2 * radius);
}
void OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) {
if (y < 0 || y >= this->height()) { return; }
if (x < 0) {
length += x;
x = 0;
}
if ( (x + length) > this->width()) {
length = (this->width() - x);
}
if (length <= 0) { return; }
uint8_t * bufferPtr = buffer;
bufferPtr += (y >> 3) * this->width();
bufferPtr += x;
uint8_t drawBit = 1 << (y & 7);
switch (color) {
case WHITE: while (length--) {
*bufferPtr++ |= drawBit;
}; break;
case BLACK: drawBit = ~drawBit; while (length--) {
*bufferPtr++ &= drawBit;
}; break;
case INVERSE: while (length--) {
*bufferPtr++ ^= drawBit;
}; break;
}
}
void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) {
if (x < 0 || x >= this->width()) return;
if (y < 0) {
length += y;
y = 0;
}
if ( (y + length) > this->height()) {
length = (this->height() - y);
}
if (length <= 0) return;
uint8_t yOffset = y & 7;
uint8_t drawBit;
uint8_t *bufferPtr = buffer;
bufferPtr += (y >> 3) * this->width();
bufferPtr += x;
if (yOffset) {
yOffset = 8 - yOffset;
drawBit = ~(0xFF >> (yOffset));
if (length < yOffset) {
drawBit &= (0xFF >> (yOffset - length));
}
switch (color) {
case WHITE: *bufferPtr |= drawBit; break;
case BLACK: *bufferPtr &= ~drawBit; break;
case INVERSE: *bufferPtr ^= drawBit; break;
}
if (length < yOffset) return;
length -= yOffset;
bufferPtr += this->width();
}
if (length >= 8) {
switch (color) {
case WHITE:
case BLACK:
drawBit = (color == WHITE) ? 0xFF : 0x00;
do {
*bufferPtr = drawBit;
bufferPtr += this->width();
length -= 8;
} while (length >= 8);
break;
case INVERSE:
do {
*bufferPtr = ~(*bufferPtr);
bufferPtr += this->width();
length -= 8;
} while (length >= 8);
break;
}
}
if (length > 0) {
drawBit = (1 << (length & 7)) - 1;
switch (color) {
case WHITE: *bufferPtr |= drawBit; break;
case BLACK: *bufferPtr &= ~drawBit; break;
case INVERSE: *bufferPtr ^= drawBit; break;
}
}
}
void OLEDDisplay::drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress) {
uint16_t radius = height / 2;
uint16_t xRadius = x + radius;
uint16_t yRadius = y + radius;
uint16_t doubleRadius = 2 * radius;
uint16_t innerRadius = radius - 2;
setColor(WHITE);
drawCircleQuads(xRadius, yRadius, radius, 0b00000110);
drawHorizontalLine(xRadius, y, width - doubleRadius + 1);
drawHorizontalLine(xRadius, y + height, width - doubleRadius + 1);
drawCircleQuads(x + width - radius, yRadius, radius, 0b00001001);
uint16_t maxProgressWidth = (width - doubleRadius - 1) * progress / 100;
fillCircle(xRadius, yRadius, innerRadius);
fillRect(xRadius + 1, y + 2, maxProgressWidth, height - 3);
fillCircle(xRadius + maxProgressWidth, yRadius, innerRadius);
}
void OLEDDisplay::drawFastImage(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *image) {
drawInternal(xMove, yMove, width, height, image, 0, 0);
}
void OLEDDisplay::drawXbm(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *xbm) {
int16_t widthInXbm = (width + 7) / 8;
uint8_t data = 0;
for(int16_t y = 0; y < height; y++) {
for(int16_t x = 0; x < width; x++ ) {
if (x & 7) {
data >>= 1; // Move a bit
} else { // Read new data every 8 bit
data = pgm_read_byte(xbm + (x / 8) + y * widthInXbm);
}
// if there is a bit draw it
if (data & 0x01) {
setPixel(xMove + x, yMove + y);
}
}
}
}
void OLEDDisplay::drawStringInternal(int16_t xMove, int16_t yMove, char* text, uint16_t textLength, uint16_t textWidth) {
uint8_t textHeight = pgm_read_byte(fontData + HEIGHT_POS);
uint8_t firstChar = pgm_read_byte(fontData + FIRST_CHAR_POS);
uint16_t sizeOfJumpTable = pgm_read_byte(fontData + CHAR_NUM_POS) * JUMPTABLE_BYTES;
uint8_t cursorX = 0;
uint8_t cursorY = 0;
switch (textAlignment) {
case TEXT_ALIGN_CENTER_BOTH:
yMove -= textHeight >> 1;
// Fallthrough
case TEXT_ALIGN_CENTER:
xMove -= textWidth >> 1; // divide by 2
break;
case TEXT_ALIGN_RIGHT:
xMove -= textWidth;
break;
case TEXT_ALIGN_LEFT:
break;
}
// Don't draw anything if it is not on the screen.
if (xMove + textWidth < 0 || xMove > this->width() ) {return;}
if (yMove + textHeight < 0 || yMove > this->width() ) {return;}
for (uint16_t j = 0; j < textLength; j++) {
int16_t xPos = xMove + cursorX;
int16_t yPos = yMove + cursorY;
byte code = text[j];
if (code >= firstChar) {
byte charCode = code - firstChar;
// 4 Bytes per char code
byte msbJumpToChar = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES ); // MSB \ JumpAddress
byte lsbJumpToChar = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_LSB); // LSB /
byte charByteSize = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_SIZE); // Size
byte currentCharWidth = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_WIDTH); // Width
// Test if the char is drawable
if (!(msbJumpToChar == 255 && lsbJumpToChar == 255)) {
// Get the position of the char data
uint16_t charDataPosition = JUMPTABLE_START + sizeOfJumpTable + ((msbJumpToChar << 8) + lsbJumpToChar);
drawInternal(xPos, yPos, currentCharWidth, textHeight, fontData, charDataPosition, charByteSize);
}
cursorX += currentCharWidth;
}
}
}
void OLEDDisplay::drawString(int16_t xMove, int16_t yMove, String strUser) {
uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);
// char* text must be freed!
char* text = utf8ascii(strUser);
uint16_t yOffset = 0;
// If the string should be centered vertically too
// we need to now how heigh the string is.
if (textAlignment == TEXT_ALIGN_CENTER_BOTH) {
uint16_t lb = 0;
// Find number of linebreaks in text
for (uint16_t i=0;text[i] != 0; i++) {
lb += (text[i] == 10);
}
// Calculate center
yOffset = (lb * lineHeight) / 2;
}
uint16_t line = 0;
char* textPart = strtok(text,"\n");
while (textPart != NULL) {
uint16_t length = strlen(textPart);
drawStringInternal(xMove, yMove - yOffset + (line++) * lineHeight, textPart, length, getStringWidth(textPart, length));
textPart = strtok(NULL, "\n");
}
free(text);
}
void OLEDDisplay::drawStringMaxWidth(int16_t xMove, int16_t yMove, uint16_t maxLineWidth, String strUser) {
uint16_t firstChar = pgm_read_byte(fontData + FIRST_CHAR_POS);
uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);
char* text = utf8ascii(strUser);
uint16_t length = strlen(text);
uint16_t lastDrawnPos = 0;
uint16_t lineNumber = 0;
uint16_t strWidth = 0;
uint16_t preferredBreakpoint = 0;
uint16_t widthAtBreakpoint = 0;
for (uint16_t i = 0; i < length; i++) {
strWidth += pgm_read_byte(fontData + JUMPTABLE_START + (text[i] - firstChar) * JUMPTABLE_BYTES + JUMPTABLE_WIDTH);
// Always try to break on a space or dash
if (text[i] == ' ' || text[i]== '-') {
preferredBreakpoint = i;
widthAtBreakpoint = strWidth;
}
if (strWidth >= maxLineWidth) {
if (preferredBreakpoint == 0) {
preferredBreakpoint = i;
widthAtBreakpoint = strWidth;
}
drawStringInternal(xMove, yMove + (lineNumber++) * lineHeight , &text[lastDrawnPos], preferredBreakpoint - lastDrawnPos, widthAtBreakpoint);
lastDrawnPos = preferredBreakpoint + 1;
// It is possible that we did not draw all letters to i so we need
// to account for the width of the chars from `i - preferredBreakpoint`
// by calculating the width we did not draw yet.
strWidth = strWidth - widthAtBreakpoint;
preferredBreakpoint = 0;
}
}
// Draw last part if needed
if (lastDrawnPos < length) {
drawStringInternal(xMove, yMove + lineNumber * lineHeight , &text[lastDrawnPos], length - lastDrawnPos, getStringWidth(&text[lastDrawnPos], length - lastDrawnPos));
}
free(text);
}
uint16_t OLEDDisplay::getStringWidth(const char* text, uint16_t length) {
uint16_t firstChar = pgm_read_byte(fontData + FIRST_CHAR_POS);
uint16_t stringWidth = 0;
uint16_t maxWidth = 0;
while (length--) {
stringWidth += pgm_read_byte(fontData + JUMPTABLE_START + (text[length] - firstChar) * JUMPTABLE_BYTES + JUMPTABLE_WIDTH);
if (text[length] == 10) {
maxWidth = max(maxWidth, stringWidth);
stringWidth = 0;
}
}
return max(maxWidth, stringWidth);
}
uint16_t OLEDDisplay::getStringWidth(String strUser) {
char* text = utf8ascii(strUser);
uint16_t length = strlen(text);
uint16_t width = getStringWidth(text, length);
free(text);
return width;
}
void OLEDDisplay::setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment) {
this->textAlignment = textAlignment;
}
void OLEDDisplay::setFont(const char *fontData) {
this->fontData = fontData;
}
void OLEDDisplay::displayOn(void) {
sendCommand(DISPLAYON);
}
void OLEDDisplay::displayOff(void) {
sendCommand(DISPLAYOFF);
}
void OLEDDisplay::invertDisplay(void) {
sendCommand(INVERTDISPLAY);
}
void OLEDDisplay::normalDisplay(void) {
sendCommand(NORMALDISPLAY);
}
void OLEDDisplay::setContrast(char contrast, char precharge, char comdetect) {
sendCommand(SETPRECHARGE); //0xD9
sendCommand(precharge); //0xF1 default, to lower the contrast, put 1-1F
sendCommand(SETCONTRAST);
sendCommand(contrast); // 0-255
sendCommand(SETVCOMDETECT); //0xDB, (additionally needed to lower the contrast)
sendCommand(comdetect); //0x40 default, to lower the contrast, put 0
sendCommand(DISPLAYALLON_RESUME);
sendCommand(NORMALDISPLAY);
sendCommand(DISPLAYON);
}
void OLEDDisplay::flipScreenVertically() {
sendCommand(SEGREMAP | 0x01);
sendCommand(COMSCANDEC); //Rotate screen 180 Deg
}
void OLEDDisplay::clear(void) {
memset(buffer, 0, DISPLAY_BUFFER_SIZE);
}
void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);
// Always align left
setTextAlignment(TEXT_ALIGN_LEFT);
// State values
uint16_t length = 0;
uint16_t line = 0;
uint16_t lastPos = 0;
for (uint16_t i=0;i<this->logBufferFilled;i++){
// Everytime we have a \n print
if (this->logBuffer[i] == 10) {
length++;
// Draw string on line `line` from lastPos to length
// Passing 0 as the lenght because we are in TEXT_ALIGN_LEFT
drawStringInternal(xMove, yMove + (line++) * lineHeight, &this->logBuffer[lastPos], length, 0);
// Remember last pos
lastPos = i;
// Reset length
length = 0;
} else {
// Count chars until next linebreak
length++;
}
}
// Draw the remaining string
if (length > 0) {
drawStringInternal(xMove, yMove + line * lineHeight, &this->logBuffer[lastPos], length, 0);
}
}
bool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars){
if (logBuffer != NULL) free(logBuffer);
uint16_t size = lines * chars;
if (size > 0) {
this->logBufferLine = 0; // Lines printed
this->logBufferFilled = 0; // Nothing stored yet
this->logBufferMaxLines = lines; // Lines max printable
this->logBufferSize = size; // Total number of characters the buffer can hold
this->logBuffer = (char *) malloc(size * sizeof(uint8_t));
if(!this->logBuffer) {
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][setLogBuffer] Not enough memory to create log buffer\n");
return false;
}
}
return true;
}
size_t OLEDDisplay::write(uint8_t c) {
if (this->logBufferSize > 0) {
// Don't waste space on \r\n line endings, dropping \r
if (c == 13) return 1;
bool maxLineNotReached = this->logBufferLine < this->logBufferMaxLines;
bool bufferNotFull = this->logBufferFilled < this->logBufferSize;
// Can we write to the buffer?
if (bufferNotFull && maxLineNotReached) {
this->logBuffer[logBufferFilled] = utf8ascii(c);
this->logBufferFilled++;
// Keep track of lines written
if (c == 10) this->logBufferLine++;
} else {
// Max line number is reached
if (!maxLineNotReached) this->logBufferLine--;
// Find the end of the first line
uint16_t firstLineEnd = 0;
for (uint16_t i=0;i<this->logBufferFilled;i++) {
if (this->logBuffer[i] == 10){
// Include last char too
firstLineEnd = i + 1;
break;
}
}
// If there was a line ending
if (firstLineEnd > 0) {
// Calculate the new logBufferFilled value
this->logBufferFilled = logBufferFilled - firstLineEnd;
// Now we move the lines infront of the buffer
memcpy(this->logBuffer, &this->logBuffer[firstLineEnd], logBufferFilled);
} else {
// Let's reuse the buffer if it was full
if (!bufferNotFull) {
this->logBufferFilled = 0;
}// else {
// Nothing to do here
//}
}
write(c);
}
}
// We are always writing all uint8_t to the buffer
return 1;
}
size_t OLEDDisplay::write(const char* str) {
if (str == NULL) return 0;
size_t length = strlen(str);
for (size_t i = 0; i < length; i++) {
write(str[i]);
}
return length;
}
// Private functions
void OLEDDisplay::sendInitCommands(void) {
sendCommand(DISPLAYOFF);
sendCommand(SETDISPLAYCLOCKDIV);
sendCommand(0xF0); // Increase speed of the display max ~96Hz
sendCommand(SETMULTIPLEX);
sendCommand(this->height() - 1);
sendCommand(SETDISPLAYOFFSET);
sendCommand(0x00);
sendCommand(SETSTARTLINE);
sendCommand(CHARGEPUMP);
sendCommand(0x14);
sendCommand(MEMORYMODE);
sendCommand(0x00);
sendCommand(SEGREMAP);
sendCommand(COMSCANINC);
sendCommand(SETCOMPINS);
sendCommand(0x12); // according to the adafruit lib, sometimes this may need to be 0x02
sendCommand(SETCONTRAST);
sendCommand(0xCF);
sendCommand(SETPRECHARGE);
sendCommand(0xF1);
sendCommand(SETVCOMDETECT); //0xDB, (additionally needed to lower the contrast)
sendCommand(0x40); //0x40 default, to lower the contrast, put 0
sendCommand(DISPLAYALLON_RESUME);
sendCommand(NORMALDISPLAY);
sendCommand(0x2e); // stop scroll
sendCommand(DISPLAYON);
}
void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *data, uint16_t offset, uint16_t bytesInData) {
if (width < 0 || height < 0) return;
if (yMove + height < 0 || yMove > this->height()) return;
if (xMove + width < 0 || xMove > this->width()) return;
uint8_t rasterHeight = 1 + ((height - 1) >> 3); // fast ceil(height / 8.0)
int8_t yOffset = yMove & 7;
bytesInData = bytesInData == 0 ? width * rasterHeight : bytesInData;
int16_t initYMove = yMove;
int8_t initYOffset = yOffset;
for (uint16_t i = 0; i < bytesInData; i++) {
// Reset if next horizontal drawing phase is started.
if ( i % rasterHeight == 0) {
yMove = initYMove;
yOffset = initYOffset;
}
byte currentByte = pgm_read_byte(data + offset + i);
int16_t xPos = xMove + (i / rasterHeight);
int16_t yPos = ((yMove >> 3) + (i % rasterHeight)) * this->width();
// int16_t yScreenPos = yMove + yOffset;
int16_t dataPos = xPos + yPos;
if (dataPos >= 0 && dataPos < DISPLAY_BUFFER_SIZE &&
xPos >= 0 && xPos < this->width() ) {
if (yOffset >= 0) {
switch (this->color) {
case WHITE: buffer[dataPos] |= currentByte << yOffset; break;
case BLACK: buffer[dataPos] &= ~(currentByte << yOffset); break;
case INVERSE: buffer[dataPos] ^= currentByte << yOffset; break;
}
if (dataPos < (DISPLAY_BUFFER_SIZE - this->width())) {
switch (this->color) {
case WHITE: buffer[dataPos + this->width()] |= currentByte >> (8 - yOffset); break;
case BLACK: buffer[dataPos + this->width()] &= ~(currentByte >> (8 - yOffset)); break;
case INVERSE: buffer[dataPos + this->width()] ^= currentByte >> (8 - yOffset); break;
}
}
} else {
// Make new offset position
yOffset = -yOffset;
switch (this->color) {
case WHITE: buffer[dataPos] |= currentByte >> yOffset; break;
case BLACK: buffer[dataPos] &= ~(currentByte >> yOffset); break;
case INVERSE: buffer[dataPos] ^= currentByte >> yOffset; break;
}
// Prepare for next iteration by moving one block up
yMove -= 8;
// and setting the new yOffset
yOffset = 8 - yOffset;
}
yield();
}
}
}
// Code form http://playground.arduino.cc/Main/Utf8ascii
uint8_t OLEDDisplay::utf8ascii(byte ascii) {
static uint8_t LASTCHAR;
if ( ascii < 128 ) { // Standard ASCII-set 0..0x7F handling
LASTCHAR = 0;
return ascii;
}
uint8_t last = LASTCHAR; // get last char
LASTCHAR = ascii;
switch (last) { // conversion depnding on first UTF8-character
case 0xC2: return (ascii); break;
case 0xC3: return (ascii | 0xC0); break;
case 0x82: if (ascii == 0xAC) return (0x80); // special case Euro-symbol
}
return 0; // otherwise: return zero, if character has to be ignored
}
// You need to free the char!
char* OLEDDisplay::utf8ascii(String str) {
uint16_t k = 0;
uint16_t length = str.length() + 1;
// Copy the string into a char array
char* s = (char*) malloc(length * sizeof(char));
if(!s) {
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][utf8ascii] Can't allocate another char array. Drop support for UTF-8.\n");
return (char*) str.c_str();
}
str.toCharArray(s, length);
length--;
for (uint16_t i=0; i < length; i++) {
char c = utf8ascii(s[i]);
if (c!=0) {
s[k++]=c;
}
}
s[k]=0;
// This will leak 's' be sure to free it in the calling function.
return s;
}
+283
View File
@@ -0,0 +1,283 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 by Daniel Eichhorn
* Copyright (c) 2016 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/
#ifndef OLEDDISPLAY_h
#define OLEDDISPLAY_h
#include <Arduino.h>
#include "OLEDDisplayFonts.h"
//#define DEBUG_OLEDDISPLAY(...) Serial.printf( __VA_ARGS__ )
#ifndef DEBUG_OLEDDISPLAY
#define DEBUG_OLEDDISPLAY(...)
#endif
// Use DOUBLE BUFFERING by default
#ifndef OLEDDISPLAY_REDUCE_MEMORY
#define OLEDDISPLAY_DOUBLE_BUFFER
#endif
// Display settings
#ifndef DISPLAY_WIDTH
#define DISPLAY_WIDTH 128
#endif
#ifndef DISPLAY_HEIGHT
#define DISPLAY_HEIGHT 64
#endif
#define DISPLAY_BUFFER_SIZE DISPLAY_WIDTH * DISPLAY_HEIGHT / 8
// Header Values
#define JUMPTABLE_BYTES 4
#define JUMPTABLE_LSB 1
#define JUMPTABLE_SIZE 2
#define JUMPTABLE_WIDTH 3
#define JUMPTABLE_START 4
#define WIDTH_POS 0
#define HEIGHT_POS 1
#define FIRST_CHAR_POS 2
#define CHAR_NUM_POS 3
// Display commands
#define CHARGEPUMP 0x8D
#define COLUMNADDR 0x21
#define COMSCANDEC 0xC8
#define COMSCANINC 0xC0
#define DISPLAYALLON 0xA5
#define DISPLAYALLON_RESUME 0xA4
#define DISPLAYOFF 0xAE
#define DISPLAYON 0xAF
#define EXTERNALVCC 0x1
#define INVERTDISPLAY 0xA7
#define MEMORYMODE 0x20
#define NORMALDISPLAY 0xA6
#define PAGEADDR 0x22
#define SEGREMAP 0xA0
#define SETCOMPINS 0xDA
#define SETCONTRAST 0x81
#define SETDISPLAYCLOCKDIV 0xD5
#define SETDISPLAYOFFSET 0xD3
#define SETHIGHCOLUMN 0x10
#define SETLOWCOLUMN 0x00
#define SETMULTIPLEX 0xA8
#define SETPRECHARGE 0xD9
#define SETSEGMENTREMAP 0xA1
#define SETSTARTLINE 0x40
#define SETVCOMDETECT 0xDB
#define SWITCHCAPVCC 0x2
#ifndef _swap_int16_t
#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; }
#endif
enum OLEDDISPLAY_COLOR {
BLACK = 0,
WHITE = 1,
INVERSE = 2
};
enum OLEDDISPLAY_TEXT_ALIGNMENT {
TEXT_ALIGN_LEFT = 0,
TEXT_ALIGN_RIGHT = 1,
TEXT_ALIGN_CENTER = 2,
TEXT_ALIGN_CENTER_BOTH = 3
};
class OLEDDisplay : public Print {
private:
const int _width, _height;
public:
OLEDDisplay(const int width = DISPLAY_WIDTH, const int height = DISPLAY_HEIGHT) : _width(width), _height(height){ };
virtual ~OLEDDisplay();
const int width(void) const { return _width; };
const int height(void) const { return _height; };
// Initialize the display
bool init();
// Free the memory used by the display
void end();
// Cycle through the initialization
void resetDisplay(void);
/* Drawing functions */
// Sets the color of all pixel operations
void setColor(OLEDDISPLAY_COLOR color);
// Draw a pixel at given position
void setPixel(int16_t x, int16_t y);
// Draw a line from position 0 to position 1
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
// Draw the border of a rectangle at the given location
void drawRect(int16_t x, int16_t y, int16_t width, int16_t height);
// Fill the rectangle
void fillRect(int16_t x, int16_t y, int16_t width, int16_t height);
// Draw the border of a circle
void drawCircle(int16_t x, int16_t y, int16_t radius);
// Draw all Quadrants specified in the quads bit mask
void drawCircleQuads(int16_t x0, int16_t y0, int16_t radius, uint8_t quads);
// Fill circle
void fillCircle(int16_t x, int16_t y, int16_t radius);
// Draw a line horizontally
void drawHorizontalLine(int16_t x, int16_t y, int16_t length);
// Draw a lin vertically
void drawVerticalLine(int16_t x, int16_t y, int16_t length);
// Draws a rounded progress bar with the outer dimensions given by width and height. Progress is
// a unsigned byte value between 0 and 100
void drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress);
// Draw a bitmap in the internal image format
void drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const char *image);
// Draw a XBM
void drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const char *xbm);
/* Text functions */
// Draws a string at the given location
void drawString(int16_t x, int16_t y, String text);
// Draws a String with a maximum width at the given location.
// If the given String is wider than the specified width
// The text will be wrapped to the next line at a space or dash
void drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, String text);
// Returns the width of the const char* with the current
// font settings
uint16_t getStringWidth(const char* text, uint16_t length);
// Convencience method for the const char version
uint16_t getStringWidth(String text);
// Specifies relative to which anchor point
// the text is rendered. Available constants:
// TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH
void setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment);
// Sets the current font. Available default fonts
// ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24
void setFont(const char *fontData);
/* Display functions */
// Turn the display on
void displayOn(void);
// Turn the display offs
void displayOff(void);
// Inverted display mode
void invertDisplay(void);
// Normal display mode
void normalDisplay(void);
// Set display contrast
// really low brightness & contrast: contrast = 10, precharge = 5, comdetect = 0
// normal brightness & contrast: contrast = 100
void setContrast(char contrast, char precharge = 241, char comdetect = 64);
// Turn the display upside down
void flipScreenVertically();
// Write the buffer to the display memory
virtual void display(void) = 0;
// Clear the local pixel buffer
void clear(void);
// Log buffer implementation
// This will define the lines and characters you can
// print to the screen. When you exeed the buffer size (lines * chars)
// the output may be truncated due to the size constraint.
bool setLogBuffer(uint16_t lines, uint16_t chars);
// Draw the log buffer at position (x, y)
void drawLogBuffer(uint16_t x, uint16_t y);
// Implementent needed function to be compatible with Print class
size_t write(uint8_t c);
size_t write(const char* s);
uint8_t *buffer = NULL;
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
uint8_t *buffer_back = NULL;
#endif
protected:
OLEDDISPLAY_TEXT_ALIGNMENT textAlignment = TEXT_ALIGN_LEFT;
OLEDDISPLAY_COLOR color = WHITE;
const char *fontData = ArialMT_Plain_10;
// State values for logBuffer
uint16_t logBufferSize = 0;
uint16_t logBufferFilled = 0;
uint16_t logBufferLine = 0;
uint16_t logBufferMaxLines = 0;
char *logBuffer = NULL;
// Send a command to the display (low level function)
virtual void sendCommand(uint8_t com) {(void)com;};
// Connect to the display
virtual bool connect() { return false; };
// Send all the init commands
void sendInitCommands();
// converts utf8 characters to extended ascii
static char* utf8ascii(String s);
static byte utf8ascii(byte ascii);
void inline drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *data, uint16_t offset, uint16_t bytesInData) __attribute__((always_inline));
void drawStringInternal(int16_t xMove, int16_t yMove, char* text, uint16_t textLength, uint16_t textWidth);
};
#endif
File diff suppressed because it is too large Load Diff
+406
View File
@@ -0,0 +1,406 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 by Daniel Eichhorn
* Copyright (c) 2016 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#include "OLEDDisplayUi.h"
OLEDDisplayUi::OLEDDisplayUi(OLEDDisplay *display) {
this->display = display;
}
void OLEDDisplayUi::init() {
this->display->init();
}
void OLEDDisplayUi::setTargetFPS(uint8_t fps){
float oldInterval = this->updateInterval;
this->updateInterval = ((float) 1.0 / (float) fps) * 1000;
// Calculate new ticksPerFrame
float changeRatio = oldInterval / (float) this->updateInterval;
this->ticksPerFrame *= changeRatio;
this->ticksPerTransition *= changeRatio;
}
// -/------ Automatic controll ------\-
void OLEDDisplayUi::enableAutoTransition(){
this->autoTransition = true;
}
void OLEDDisplayUi::disableAutoTransition(){
this->autoTransition = false;
}
void OLEDDisplayUi::setAutoTransitionForwards(){
this->state.frameTransitionDirection = 1;
this->lastTransitionDirection = 1;
}
void OLEDDisplayUi::setAutoTransitionBackwards(){
this->state.frameTransitionDirection = -1;
this->lastTransitionDirection = -1;
}
void OLEDDisplayUi::setTimePerFrame(uint16_t time){
this->ticksPerFrame = (int) ( (float) time / (float) updateInterval);
}
void OLEDDisplayUi::setTimePerTransition(uint16_t time){
this->ticksPerTransition = (int) ( (float) time / (float) updateInterval);
}
// -/------ Customize indicator position and style -------\-
void OLEDDisplayUi::enableIndicator(){
this->state.isIndicatorDrawen = true;
}
void OLEDDisplayUi::disableIndicator(){
this->state.isIndicatorDrawen = false;
}
void OLEDDisplayUi::enableAllIndicators(){
this->shouldDrawIndicators = true;
}
void OLEDDisplayUi::disableAllIndicators(){
this->shouldDrawIndicators = false;
}
void OLEDDisplayUi::setIndicatorPosition(IndicatorPosition pos) {
this->indicatorPosition = pos;
}
void OLEDDisplayUi::setIndicatorDirection(IndicatorDirection dir) {
this->indicatorDirection = dir;
}
void OLEDDisplayUi::setActiveSymbol(const char* symbol) {
this->activeSymbol = symbol;
}
void OLEDDisplayUi::setInactiveSymbol(const char* symbol) {
this->inactiveSymbol = symbol;
}
// -/----- Frame settings -----\-
void OLEDDisplayUi::setFrameAnimation(AnimationDirection dir) {
this->frameAnimationDirection = dir;
}
void OLEDDisplayUi::setFrames(FrameCallback* frameFunctions, uint8_t frameCount) {
this->frameFunctions = frameFunctions;
this->frameCount = frameCount;
this->resetState();
}
// -/----- Overlays ------\-
void OLEDDisplayUi::setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount){
this->overlayFunctions = overlayFunctions;
this->overlayCount = overlayCount;
}
// -/----- Loading Process -----\-
void OLEDDisplayUi::setLoadingDrawFunction(LoadingDrawFunction loadingDrawFunction) {
this->loadingDrawFunction = loadingDrawFunction;
}
void OLEDDisplayUi::runLoadingProcess(LoadingStage* stages, uint8_t stagesCount) {
uint8_t progress = 0;
uint8_t increment = 100 / stagesCount;
for (uint8_t i = 0; i < stagesCount; i++) {
display->clear();
this->loadingDrawFunction(this->display, &stages[i], progress);
display->display();
stages[i].callback();
progress += increment;
yield();
}
display->clear();
this->loadingDrawFunction(this->display, &stages[stagesCount-1], progress);
display->display();
delay(150);
}
// -/----- Manuel control -----\-
void OLEDDisplayUi::nextFrame() {
if (this->state.frameState != IN_TRANSITION) {
this->state.manuelControll = true;
this->state.frameState = IN_TRANSITION;
this->state.ticksSinceLastStateSwitch = 0;
this->lastTransitionDirection = this->state.frameTransitionDirection;
this->state.frameTransitionDirection = 1;
}
}
void OLEDDisplayUi::previousFrame() {
if (this->state.frameState != IN_TRANSITION) {
this->state.manuelControll = true;
this->state.frameState = IN_TRANSITION;
this->state.ticksSinceLastStateSwitch = 0;
this->lastTransitionDirection = this->state.frameTransitionDirection;
this->state.frameTransitionDirection = -1;
}
}
void OLEDDisplayUi::switchToFrame(uint8_t frame) {
if (frame >= this->frameCount) return;
this->state.ticksSinceLastStateSwitch = 0;
if (frame == this->state.currentFrame) return;
this->state.frameState = FIXED;
this->state.currentFrame = frame;
this->state.isIndicatorDrawen = true;
}
void OLEDDisplayUi::transitionToFrame(uint8_t frame) {
if (frame >= this->frameCount) return;
this->state.ticksSinceLastStateSwitch = 0;
if (frame == this->state.currentFrame) return;
this->nextFrameNumber = frame;
this->lastTransitionDirection = this->state.frameTransitionDirection;
this->state.manuelControll = true;
this->state.frameState = IN_TRANSITION;
this->state.frameTransitionDirection = frame < this->state.currentFrame ? -1 : 1;
}
// -/----- State information -----\-
OLEDDisplayUiState* OLEDDisplayUi::getUiState(){
return &this->state;
}
int8_t OLEDDisplayUi::update(){
long frameStart = millis();
int8_t timeBudget = this->updateInterval - (frameStart - this->state.lastUpdate);
if ( timeBudget <= 0) {
// Implement frame skipping to ensure time budget is keept
if (this->autoTransition && this->state.lastUpdate != 0) this->state.ticksSinceLastStateSwitch += ceil(-timeBudget / this->updateInterval);
this->state.lastUpdate = frameStart;
this->tick();
}
return this->updateInterval - (millis() - frameStart);
}
void OLEDDisplayUi::tick() {
this->state.ticksSinceLastStateSwitch++;
switch (this->state.frameState) {
case IN_TRANSITION:
if (this->state.ticksSinceLastStateSwitch >= this->ticksPerTransition){
this->state.frameState = FIXED;
this->state.currentFrame = getNextFrameNumber();
this->state.ticksSinceLastStateSwitch = 0;
this->nextFrameNumber = -1;
}
break;
case FIXED:
// Revert manuelControll
if (this->state.manuelControll) {
this->state.frameTransitionDirection = this->lastTransitionDirection;
this->state.manuelControll = false;
}
if (this->state.ticksSinceLastStateSwitch >= this->ticksPerFrame){
if (this->autoTransition){
this->state.frameState = IN_TRANSITION;
}
this->state.ticksSinceLastStateSwitch = 0;
}
break;
}
this->display->clear();
this->drawFrame();
if (shouldDrawIndicators) {
this->drawIndicator();
}
this->drawOverlays();
this->display->display();
}
void OLEDDisplayUi::resetState() {
this->state.lastUpdate = 0;
this->state.ticksSinceLastStateSwitch = 0;
this->state.frameState = FIXED;
this->state.currentFrame = 0;
this->state.isIndicatorDrawen = true;
}
void OLEDDisplayUi::drawFrame(){
switch (this->state.frameState){
case IN_TRANSITION: {
float progress = (float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition;
int16_t x = 0, y = 0, x1 = 0, y1 = 0;
switch(this->frameAnimationDirection){
case SLIDE_LEFT:
x = -this->display->width() * progress;
y = 0;
x1 = x + this->display->width();
y1 = 0;
break;
case SLIDE_RIGHT:
x = this->display->width() * progress;
y = 0;
x1 = x - this->display->width();
y1 = 0;
break;
case SLIDE_UP:
x = 0;
y = -this->display->height() * progress;
x1 = 0;
y1 = y + this->display->height();
break;
case SLIDE_DOWN:
x = 0;
y = this->display->height() * progress;
x1 = 0;
y1 = y - this->display->height();
break;
}
// Invert animation if direction is reversed.
int8_t dir = this->state.frameTransitionDirection >= 0 ? 1 : -1;
x *= dir; y *= dir; x1 *= dir; y1 *= dir;
bool drawenCurrentFrame;
// Prope each frameFunction for the indicator Drawen state
this->enableIndicator();
(this->frameFunctions[this->state.currentFrame])(this->display, &this->state, x, y);
drawenCurrentFrame = this->state.isIndicatorDrawen;
this->enableIndicator();
(this->frameFunctions[this->getNextFrameNumber()])(this->display, &this->state, x1, y1);
// Build up the indicatorDrawState
if (drawenCurrentFrame && !this->state.isIndicatorDrawen) {
// Drawen now but not next
this->indicatorDrawState = 2;
} else if (!drawenCurrentFrame && this->state.isIndicatorDrawen) {
// Not drawen now but next
this->indicatorDrawState = 1;
} else if (!drawenCurrentFrame && !this->state.isIndicatorDrawen) {
// Not drawen in both frames
this->indicatorDrawState = 3;
}
// If the indicator isn't draw in the current frame
// reflect it in state.isIndicatorDrawen
if (!drawenCurrentFrame) this->state.isIndicatorDrawen = false;
break;
}
case FIXED:
// Always assume that the indicator is drawn!
// And set indicatorDrawState to "not known yet"
this->indicatorDrawState = 0;
this->enableIndicator();
(this->frameFunctions[this->state.currentFrame])(this->display, &this->state, 0, 0);
break;
}
}
void OLEDDisplayUi::drawIndicator() {
// Only draw if the indicator is invisible
// for both frames or
// the indiactor is shown and we are IN_TRANSITION
if (this->indicatorDrawState == 3 || (!this->state.isIndicatorDrawen && this->state.frameState != IN_TRANSITION)) {
return;
}
uint8_t posOfHighlightFrame = 0;
float indicatorFadeProgress = 0;
// if the indicator needs to be slided in we want to
// highlight the next frame in the transition
uint8_t frameToHighlight = this->indicatorDrawState == 1 ? this->getNextFrameNumber() : this->state.currentFrame;
// Calculate the frame that needs to be highlighted
// based on the Direction the indiactor is drawn
switch (this->indicatorDirection){
case LEFT_RIGHT:
posOfHighlightFrame = frameToHighlight;
break;
case RIGHT_LEFT:
posOfHighlightFrame = this->frameCount - frameToHighlight;
break;
}
switch (this->indicatorDrawState) {
case 1: // Indicator was not drawn in this frame but will be in next
// Slide IN
indicatorFadeProgress = 1 - ((float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition);
break;
case 2: // Indicator was drawn in this frame but not in next
// Slide OUT
indicatorFadeProgress = ((float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition);
break;
}
uint16_t frameStartPos = (12 * frameCount / 2);
const char *image;
uint16_t x = 0, y = 0;
for (byte i = 0; i < this->frameCount; i++) {
switch (this->indicatorPosition){
case TOP:
y = 0 - (8 * indicatorFadeProgress);
x = (this->display->width() / 2) - frameStartPos + 12 * i;
break;
case BOTTOM:
y = (this->display->height() - 8) + (8 * indicatorFadeProgress);
x = (this->display->width() / 2) - frameStartPos + 12 * i;
break;
case RIGHT:
x = (this->display->width() - 8) + (8 * indicatorFadeProgress);
y = (this->display->height() / 2) - frameStartPos + 2 + 12 * i;
break;
case LEFT:
x = 0 - (8 * indicatorFadeProgress);
y = (this->display->height() / 2) - frameStartPos + 2 + 12 * i;
break;
}
if (posOfHighlightFrame == i) {
image = this->activeSymbol;
} else {
image = this->inactiveSymbol;
}
this->display->drawFastImage(x, y, 8, 8, image);
}
}
void OLEDDisplayUi::drawOverlays() {
for (uint8_t i=0;i<this->overlayCount;i++){
(this->overlayFunctions[i])(this->display, &this->state);
}
}
uint8_t OLEDDisplayUi::getNextFrameNumber(){
if (this->nextFrameNumber != -1) return this->nextFrameNumber;
return (this->state.currentFrame + this->frameCount + this->state.frameTransitionDirection) % this->frameCount;
}
+305
View File
@@ -0,0 +1,305 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 by Daniel Eichhorn
* Copyright (c) 2016 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#ifndef OLEDDISPLAYUI_h
#define OLEDDISPLAYUI_h
#include <Arduino.h>
#include "OLEDDisplay.h"
//#define DEBUG_OLEDDISPLAYUI(...) Serial.printf( __VA_ARGS__ )
#ifndef DEBUG_OLEDDISPLAYUI
#define DEBUG_OLEDDISPLAYUI(...)
#endif
enum AnimationDirection {
SLIDE_UP,
SLIDE_DOWN,
SLIDE_LEFT,
SLIDE_RIGHT
};
enum IndicatorPosition {
TOP,
RIGHT,
BOTTOM,
LEFT
};
enum IndicatorDirection {
LEFT_RIGHT,
RIGHT_LEFT
};
enum FrameState {
IN_TRANSITION,
FIXED
};
const char ANIMATION_activeSymbol[] PROGMEM = {
0x00, 0x18, 0x3c, 0x7e, 0x7e, 0x3c, 0x18, 0x00
};
const char ANIMATION_inactiveSymbol[] PROGMEM = {
0x00, 0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x00
};
// Structure of the UiState
struct OLEDDisplayUiState {
uint64_t lastUpdate = 0;
uint16_t ticksSinceLastStateSwitch = 0;
FrameState frameState = FIXED;
uint8_t currentFrame = 0;
bool isIndicatorDrawen = true;
// Normal = 1, Inverse = -1;
int8_t frameTransitionDirection = 1;
bool manuelControll = false;
// Custom data that can be used by the user
void* userData = NULL;
};
struct LoadingStage {
const char* process;
void (*callback)();
};
typedef void (*FrameCallback)(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
typedef void (*OverlayCallback)(OLEDDisplay *display, OLEDDisplayUiState* state);
typedef void (*LoadingDrawFunction)(OLEDDisplay *display, LoadingStage* stage, uint8_t progress);
class OLEDDisplayUi {
private:
OLEDDisplay *display;
// Symbols for the Indicator
IndicatorPosition indicatorPosition = BOTTOM;
IndicatorDirection indicatorDirection = LEFT_RIGHT;
const char* activeSymbol = ANIMATION_activeSymbol;
const char* inactiveSymbol = ANIMATION_inactiveSymbol;
bool shouldDrawIndicators = true;
// Values for the Frames
AnimationDirection frameAnimationDirection = SLIDE_RIGHT;
int8_t lastTransitionDirection = 1;
uint16_t ticksPerFrame = 151; // ~ 5000ms at 30 FPS
uint16_t ticksPerTransition = 15; // ~ 500ms at 30 FPS
bool autoTransition = true;
FrameCallback* frameFunctions;
uint8_t frameCount = 0;
// Internally used to transition to a specific frame
int8_t nextFrameNumber = -1;
// Values for Overlays
OverlayCallback* overlayFunctions;
uint8_t overlayCount = 0;
// Will the Indicator be drawen
// 3 Not drawn in both frames
// 2 Drawn this frame but not next
// 1 Not drown this frame but next
// 0 Not known yet
uint8_t indicatorDrawState = 1;
// Loading screen
LoadingDrawFunction loadingDrawFunction = [](OLEDDisplay *display, LoadingStage* stage, uint8_t progress) {
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(ArialMT_Plain_10);
display->drawString(64, 18, stage->process);
display->drawProgressBar(4, 32, 120, 8, progress);
};
// UI State
OLEDDisplayUiState state;
// Bookeeping for update
uint8_t updateInterval = 33;
uint8_t getNextFrameNumber();
void drawIndicator();
void drawFrame();
void drawOverlays();
void tick();
void resetState();
public:
OLEDDisplayUi(OLEDDisplay *display);
/**
* Initialise the display
*/
void init();
/**
* Configure the internal used target FPS
*/
void setTargetFPS(uint8_t fps);
// Automatic Controll
/**
* Enable automatic transition to next frame after the some time can be configured with `setTimePerFrame` and `setTimePerTransition`.
*/
void enableAutoTransition();
/**
* Disable automatic transition to next frame.
*/
void disableAutoTransition();
/**
* Set the direction if the automatic transitioning
*/
void setAutoTransitionForwards();
void setAutoTransitionBackwards();
/**
* Set the approx. time a frame is displayed
*/
void setTimePerFrame(uint16_t time);
/**
* Set the approx. time a transition will take
*/
void setTimePerTransition(uint16_t time);
// Customize indicator position and style
/**
* Draw the indicator.
* This is the defaut state for all frames if
* the indicator was hidden on the previous frame
* it will be slided in.
*/
void enableIndicator();
/**
* Don't draw the indicator.
* This will slide out the indicator
* when transitioning to the next frame.
*/
void disableIndicator();
/**
* Enable drawing of indicators
*/
void enableAllIndicators();
/**
* Disable draw of indicators.
*/
void disableAllIndicators();
/**
* Set the position of the indicator bar.
*/
void setIndicatorPosition(IndicatorPosition pos);
/**
* Set the direction of the indicator bar. Defining the order of frames ASCENDING / DESCENDING
*/
void setIndicatorDirection(IndicatorDirection dir);
/**
* Set the symbol to indicate an active frame in the indicator bar.
*/
void setActiveSymbol(const char* symbol);
/**
* Set the symbol to indicate an inactive frame in the indicator bar.
*/
void setInactiveSymbol(const char* symbol);
// Frame settings
/**
* Configure what animation is used to transition from one frame to another
*/
void setFrameAnimation(AnimationDirection dir);
/**
* Add frame drawing functions
*/
void setFrames(FrameCallback* frameFunctions, uint8_t frameCount);
// Overlay
/**
* Add overlays drawing functions that are draw independent of the Frames
*/
void setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount);
// Loading animation
/**
* Set the function that will draw each step
* in the loading animation
*/
void setLoadingDrawFunction(LoadingDrawFunction loadingFunction);
/**
* Run the loading process
*/
void runLoadingProcess(LoadingStage* stages, uint8_t stagesCount);
// Manual Control
void nextFrame();
void previousFrame();
/**
* Switch without transition to frame `frame`.
*/
void switchToFrame(uint8_t frame);
/**
* Transition to frame `frame`, when the `frame` number is bigger than the current
* frame the forward animation will be used, otherwise the backwards animation is used.
*/
void transitionToFrame(uint8_t frame);
// State Info
OLEDDisplayUiState* getUiState();
int8_t update();
};
#endif
@@ -0,0 +1,40 @@
#define espeasy_logo_width 36
#define espeasy_logo_height 36
const char espeasy_logo_bits[] PROGMEM= {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x60, 0x40, 0xc0, 0x00, 0x00, 0x70, 0xf0, 0xe0,
0x01, 0x00, 0x78, 0xf8, 0xf0, 0x01, 0x00, 0x3c, 0x7c, 0xf8, 0x00, 0x00,
0x1e, 0x3e, 0x7c, 0x00, 0x00, 0x0f, 0x1f, 0x3e, 0x00, 0x80, 0x87, 0x0f,
0x1f, 0x00, 0xc0, 0xc3, 0x87, 0x0f, 0x00, 0xe0, 0xe1, 0xc3, 0x07, 0x00,
0xf0, 0xf0, 0xe1, 0xc3, 0x00, 0x78, 0xf8, 0xf0, 0xe1, 0x01, 0x30, 0x7c,
0xf8, 0xf0, 0x00, 0x00, 0x3e, 0x7c, 0x78, 0x00, 0x00, 0x1f, 0x3e, 0x3c,
0x00, 0x80, 0x0f, 0x1f, 0x1e, 0x00, 0xc0, 0x87, 0x0f, 0x0f, 0x00, 0xe0,
0xc3, 0x87, 0x07, 0x00, 0xf0, 0xe1, 0xc3, 0x03, 0x00, 0xf0, 0xf0, 0xe1,
0x01, 0x00, 0x78, 0xf8, 0xf0, 0x00, 0x00, 0x30, 0x7c, 0x78, 0x00, 0x00,
0x00, 0x3e, 0x3c, 0x00, 0x00, 0x00, 0x1f, 0x1e, 0x00, 0x00, 0x80, 0x0f,
0x0f, 0x78, 0x00, 0xc0, 0x87, 0x07, 0xfc, 0x00, 0xe0, 0xc3, 0x03, 0xfc,
0x01, 0xf0, 0xe1, 0x01, 0xfc, 0x01, 0xf8, 0xf0, 0x00, 0xfc, 0x00, 0x78,
0x70, 0x00, 0x78, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
const char activeSymbole[] PROGMEM = {
B00000000,
B00000000,
B00011000,
B00100100,
B01000010,
B01000010,
B00100100,
B00011000
};
const char inactiveSymbole[] PROGMEM = {
B00000000,
B00000000,
B00000000,
B00000000,
B00011000,
B00011000,
B00000000,
B00000000
};
+260 -56
View File
@@ -1,20 +1,34 @@
# esp8266-oled-ssd1306
esp8266-oled-ssd1306 [![Build Status](https://travis-ci.org/squix78/esp8266-oled-ssd1306.svg?branch=dev-branch-3.0.0)](https://travis-ci.org/squix78/esp8266-oled-ssd1306)
============
> We just released version 3.0.0. Please have a look at our [upgrade guide](UPGRADE-3.0.md)
This is a driver for the SSD1306 based 128x64 pixel OLED display running on the Arduino/ESP8266 platform.
Can be used with either the I2C or SPI version of the display
You can either download this library as a zip file and unpack it to your Arduino/libraries folder or (once it has been added) choose it from the Arduino library manager.
It is also available as a platformio library. Just execute the following command:
```
platformio lib install 562
```
## Credits
Many thanks go to Fabrice Weinberg (@FWeinb) for optimizing and refactoring the UI library.
The init sequence for the SSD1306 was inspired by Adafruits library for the same display.
This library has initially been written by Daniel Eichhorn (@squix78). Many thanks go to Fabrice Weinberg (@FWeinb) for optimizing and refactoring many aspects of the library. Also many thanks to the many committers who helped to add new features and who fixed many bugs.
The init sequence for the SSD1306 was inspired by Adafruit's library for the same display.
## Usage
The SSD1306Demo is a very comprehensive example demonstrating the most important features of the library.
Check out the examples folder for a few comprehensive demonstrations how to use the library. Also check out the ESP8266 Weather Station library (https://github.com/squix78/esp8266-weather-station) which uses the OLED library to display beautiful weather information.
## Upgrade
The API changed a lot with the 3.0 release. If you were using this library with older versions please have a look at the [Upgrade Guide](UPGRADE-3.0.md).
## Features
* Draw pixels at given coordinates
* Draw lines from given coordinates to given coordinates
* Draw or fill a rectangle with given dimensions
* Draw Text at given coordinates:
* Define Alignment: Left, Right and Center
@@ -32,20 +46,72 @@ Fonts are defined in a proprietary but open format. You can create new font file
of open sourced Fonts from this web app: http://oleddisplay.squix.ch
Choose the font family, style and size, check the preview image and if you like what you see click the "Create" button. This will create the font array in a text area form where you can copy and paste it into a new or existing header file.
![FontTool](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/FontTool.png)
## Hardware Abstraction
The library supports different protocols to access the OLED display. Currently there is support for I2C using the built in Wire.h library, I2C by using the much faster BRZO I2C library [https://github.com/pasko-zh/brzo_i2c] written in assembler and it also supports displays which come with the SPI interface.
### I2C with Wire.h
```C++
#include <Wire.h>
#include "SSD1306.h"
SSD1306 display(ADDRESS, SDA, SDC);
```
or for a SH1106:
```C++
#include <Wire.h>
#include "SH1106.h"
SH1106 display(ADDRESS, SDA, SDC);
```
### I2C with brzo_i2c
```C++
#include <brzo_i2c.h>
#include "SSD1306Brzo.h"
SSD1306Brzo display(ADDRESS, SDA, SDC);
```
or for the SH1106:
```C++
#include <brzo_i2c.h>
#include "SH1106Brzo.h"
SH1106Brzo display(ADDRESS, SDA, SDC);
```
### SPI
```C++
#include <SPI.h>
#include "SSD1306Spi.h"
SSD1306Spi display(RES, DC, CS);
```
or for the SH1106:
```C++
#include <SPI.h>
#include "SH1106Spi.h"
SH1106Spi display(RES, DC, CS);
```
## API
### Display Control
```C++
// Create the display object connected to pin sda and sdc
SSD1306(int i2cAddress, int sda, int sdc);
// Initialize the display
void init();
// Free the memory used by the display
void end();
// Cycle through the initialization
void resetDisplay(void);
@@ -64,101 +130,227 @@ void clear(void);
// Write the buffer to the display memory
void display(void);
// Inverted display mode
void invertDisplay(void);
// Normal display mode
void normalDisplay(void);
// Set display contrast
void setContrast(char contrast);
// Turn the display upside down
void flipScreenVertically();
// Send a command to the display (low level function)
void sendCommand(unsigned char com);
// Send all the init commands
void sendInitCommands(void);
```
## Pixel drawing
```C++
// Draw a pixel at given position
void setPixel(int x, int y);
// Draw 8 bits at the given position
void setChar(int x, int y, unsigned char data);
/* Drawing functions */
// Sets the color of all pixel operations
void setColor(OLEDDISPLAY_COLOR color);
// Draw a pixel at given position
void setPixel(int16_t x, int16_t y);
// Draw a line from position 0 to position 1
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
// Draw the border of a rectangle at the given location
void drawRect(int x, int y, int width, int height);
void drawRect(int16_t x, int16_t y, int16_t width, int16_t height);
// Fill the rectangle
void fillRect(int x, int y, int width, int height);
void fillRect(int16_t x, int16_t y, int16_t width, int16_t height);
// Draw a bitmap with the given dimensions
void drawBitmap(int x, int y, int width, int height, const char *bitmap);
// Draw the border of a circle
void drawCircle(int16_t x, int16_t y, int16_t radius);
// Draw an XBM image with the given dimensions
void drawXbm(int x, int y, int width, int height, const char *xbm);
// Fill circle
void fillCircle(int16_t x, int16_t y, int16_t radius);
// Sets the color of all pixel operations
void setColor(int color);
// Draw a line horizontally
void drawHorizontalLine(int16_t x, int16_t y, int16_t length);
// Draw a lin vertically
void drawVerticalLine(int16_t x, int16_t y, int16_t length);
// Draws a rounded progress bar with the outer dimensions given by width and height. Progress is
// a unsigned byte value between 0 and 100
void drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress);
// Draw a bitmap in the internal image format
void drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const char *image);
// Draw a XBM
void drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const char* xbm);
```
## Text operations
``` C++
// Draws a string at the given location
void drawString(int x, int y, String text);
void drawString(int16_t x, int16_t y, String text);
// Draws a String with a maximum width at the given location.
// If the given String is wider than the specified width
// The text will be wrapped to the next line at a space or dash
void drawStringMaxWidth(int x, int y, int maxLineWidth, String text);
void drawStringMaxWidth(int16_t x, int16_t y, int16_t maxLineWidth, String text);
// Returns the width of the String with the current
// Returns the width of the const char* with the current
// font settings
int getStringWidth(String text);
uint16_t getStringWidth(const char* text, uint16_t length);
// Convencience method for the const char version
uint16_t getStringWidth(String text);
// Specifies relative to which anchor point
// the text is rendered. Available constants:
// TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT
void setTextAlignment(int textAlignment);
// TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH
void setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment);
// Sets the current font. Available default fonts
// defined in SSD1306Fonts.h:
// ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24
// Or create one with the font tool at http://oleddisplay.squix.ch
void setFont(const char *fontData);
void setFont(const char* fontData);
```
## Frame Transition Functions
## Ui Library (OLEDDisplayUi)
The Ui Library is used to provide a basic set of Ui elements called, `Frames` and `Overlays`. A `Frame` is used to provide
information the default behaviour is to display a `Frame` for a defined time and than move to the next. The library also provides an `Indicator` that will be updated accordingly. An `Overlay` on the other hand is a pieces of information (e.g. a clock) that is displayed always at the same position.
The Frame Transition functions are a set of functions on top of the basic library. They allow you to easily write frames which will be shifted in regular intervals. The frame animation (including the frame indicators) will only be activated if you define callback functions with setFrameCallacks(..). If no callback methods are defined no indicators will be displayed.
```C++
// Sets the callback methods of the format void method(x,y). As soon as you define the callbacks
// the library is in "frame mode" and indicators will be drawn.
void setFrameCallbacks(int frameCount, void (*frameCallbacks[])(SSD1306 *display, SSD1306UiState* state,int x, int y));
/**
* Initialise the display
*/
void init();
// Tells the framework to move to the next tick. The
// current visible frame callback will be called once
// per tick
void nextFrameTick(void);
/**
* Configure the internal used target FPS
*/
void setTargetFPS(uint8_t fps);
// Draws the frame indicators. In a normal setup
// the framework does this for you
void drawIndicators(int frameCount, int activeFrame);
/**
* Enable automatic transition to next frame after the some time can be configured with
* `setTimePerFrame` and `setTimePerTransition`.
*/
void enableAutoTransition();
// defines how many ticks a frame should remain visible
// This does not include the transition
void setFrameWaitTicks(int frameWaitTicks);
/**
* Disable automatic transition to next frame.
*/
void disableAutoTransition();
// Defines how many ticks should be used for a transition
void setFrameTransitionTicks(int frameTransitionTicks);
/**
* Set the direction if the automatic transitioning
*/
void setAutoTransitionForwards();
void setAutoTransitionBackwards();
// Returns the current state of the internal state machine
// Possible values: FRAME_STATE_FIX, FRAME_STATE_TRANSITION
// You can use this to detect when there is no transition
// on the way to execute operations that would
int getFrameState();
/**
* Set the approx. time a frame is displayed
*/
void setTimePerFrame(uint16_t time);
/**
* Set the approx. time a transition will take
*/
void setTimePerTransition(uint16_t time);
/**
* Draw the indicator.
* This is the default state for all frames if
* the indicator was hidden on the previous frame
* it will be slided in.
*/
void enableIndicator();
/**
* Don't draw the indicator.
* This will slide out the indicator
* when transitioning to the next frame.
*/
void disableIndicator();
/**
* Enable drawing of all indicators.
*/
void enableAllIndicators();
/**
* Disable drawing of all indicators.
*/
void disableAllIndicators();
/**
* Set the position of the indicator bar.
*/
void setIndicatorPosition(IndicatorPosition pos);
/**
* Set the direction of the indicator bar. Defining the order of frames ASCENDING / DESCENDING
*/
void setIndicatorDirection(IndicatorDirection dir);
/**
* Set the symbol to indicate an active frame in the indicator bar.
*/
void setActiveSymbol(const char* symbol);
/**
* Set the symbol to indicate an inactive frame in the indicator bar.
*/
void setInactiveSymbol(const char* symbol);
/**
* Configure what animation is used to transition from one frame to another
*/
void setFrameAnimation(AnimationDirection dir);
/**
* Add frame drawing functions
*/
void setFrames(FrameCallback* frameFunctions, uint8_t frameCount);
/**
* Add overlays drawing functions that are draw independent of the Frames
*/
void setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount);
/**
* Set the function that will draw each step
* in the loading animation
*/
void setLoadingDrawFunction(LoadingDrawFunction loadingDrawFunction);
/**
* Run the loading process
*/
void runLoadingProcess(LoadingStage* stages, uint8_t stagesCount);
// Manuell Controll
void nextFrame();
void previousFrame();
/**
* Switch without transition to frame `frame`.
*/
void switchToFrame(uint8_t frame);
/**
* Transition to frame `frame`, when the `frame` number is bigger than the current
* frame the forward animation will be used, otherwise the backwards animation is used.
*/
void transitionToFrame(uint8_t frame);
// State Info
OLEDDisplayUiState* getUiState();
// This needs to be called in the main loop
// the returned value is the remaining time (in ms)
// you have to draw after drawing to keep the frame budget.
int8_t update();
```
## Example: SSD1306Demo
@@ -187,3 +379,15 @@ This frame demonstrates the text alignment. The coordinates in the frame show re
![DemoFrame4](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame4.jpg)
This shows how to use define a maximum width after which the driver automatically wraps a word to the next line. This comes in very handy if you have longer texts to display.
### SPI version
![SPIVersion](https://github.com/neptune2/esp8266-oled-ssd1306/raw/master/resources/SPI_version.jpg)
This shows the code working on the SPI version of the display. See demo code for ESP8266 pins used.
## Project using this library
* [QRCode ESP8266](https://github.com/anunpanya/ESP8266_QRcode) (by @anunpanya)
* [Scan I2C](https://github.com/hallard/Scan-I2C-WiFi) (by @hallard)
* [Weather Station](https://github.com/squix78/esp8266-weather-station) (by @squix)
+36
View File
@@ -0,0 +1,36 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 by Daniel Eichhorn
* Copyright (c) 2016 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/
#ifndef SH1106_h
#define SH1106_h
#include "SH1106Wire.h"
// For make SH1106 an alias for SH1106Wire
typedef SH1106Wire SH1106;
#endif
+133
View File
@@ -0,0 +1,133 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 by Daniel Eichhorn
* Copyright (c) 2016 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/
#ifndef SH1106Brzo_h
#define SH1106Brzo_h
#include "OLEDDisplay.h"
#include <brzo_i2c.h>
#if F_CPU == 160000000L
#define BRZO_I2C_SPEED 1000
#else
#define BRZO_I2C_SPEED 800
#endif
class SH1106Brzo : public OLEDDisplay {
private:
uint8_t _address;
uint8_t _sda;
uint8_t _scl;
public:
SH1106Brzo(uint8_t _address, uint8_t _sda, uint8_t _scl) {
this->_address = _address;
this->_sda = _sda;
this->_scl = _scl;
}
bool connect(){
brzo_i2c_setup(_sda, _scl, 0);
return true;
}
void display(void) {
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
uint8_t minBoundY = ~0;
uint8_t maxBoundY = 0;
uint8_t minBoundX = ~0;
uint8_t maxBoundX = 0;
uint8_t x, y;
// Calculate the Y bounding box of changes
// and copy buffer[pos] to buffer_back[pos];
for (y = 0; y < (DISPLAY_HEIGHT / 8); y++) {
for (x = 0; x < DISPLAY_WIDTH; x++) {
uint16_t pos = x + y * DISPLAY_WIDTH;
if (buffer[pos] != buffer_back[pos]) {
minBoundY = _min(minBoundY, y);
maxBoundY = _max(maxBoundY, y);
minBoundX = _min(minBoundX, x);
maxBoundX = _max(maxBoundX, x);
}
buffer_back[pos] = buffer[pos];
}
yield();
}
// If the minBoundY wasn't updated
// we can savely assume that buffer_back[pos] == buffer[pos]
// holdes true for all values of pos
if (minBoundY == ~0) return;
byte k = 0;
uint8_t sendBuffer[17];
sendBuffer[0] = 0x40;
// Calculate the colum offset
uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F;
uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 );
brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED);
for (y = minBoundY; y <= maxBoundY; y++) {
sendCommand(0xB0 + y);
sendCommand(minBoundXp2H);
sendCommand(minBoundXp2L);
for (x = minBoundX; x <= maxBoundX; x++) {
k++;
sendBuffer[k] = buffer[x + y * DISPLAY_WIDTH];
if (k == 16) {
brzo_i2c_write(sendBuffer, 17, true);
k = 0;
}
}
if (k != 0) {
brzo_i2c_write(sendBuffer, k + 1, true);
k = 0;
}
yield();
}
if (k != 0) {
brzo_i2c_write(sendBuffer, k + 1, true);
}
brzo_i2c_end_transaction();
#else
#endif
}
private:
inline void sendCommand(uint8_t com) __attribute__((always_inline)){
uint8_t command[2] = {0x80 /* command mode */, com};
brzo_i2c_start_transaction(_address, BRZO_I2C_SPEED);
brzo_i2c_write(command, 2, true);
brzo_i2c_end_transaction();
}
};
#endif
+128
View File
@@ -0,0 +1,128 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 by Daniel Eichhorn
* Copyright (c) 2016 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/
#ifndef SH1106Spi_h
#define SH1106Spi_h
#include "OLEDDisplay.h"
#include <SPI.h>
class SH1106Spi : public OLEDDisplay {
private:
uint8_t _rst;
uint8_t _dc;
public:
SH1106Spi(uint8_t _rst, uint8_t _dc) {
this->_rst = _rst;
this->_dc = _dc;
}
bool connect(){
pinMode(_dc, OUTPUT);
pinMode(_rst, OUTPUT);
SPI.begin ();
SPI.setClockDivider (SPI_CLOCK_DIV2);
// Pulse Reset low for 10ms
digitalWrite(_rst, HIGH);
delay(1);
digitalWrite(_rst, LOW);
delay(10);
digitalWrite(_rst, HIGH);
return true;
}
void display(void) {
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
uint8_t minBoundY = ~0;
uint8_t maxBoundY = 0;
uint8_t minBoundX = ~0;
uint8_t maxBoundX = 0;
uint8_t x, y;
// Calculate the Y bounding box of changes
// and copy buffer[pos] to buffer_back[pos];
for (y = 0; y < (DISPLAY_HEIGHT / 8); y++) {
for (x = 0; x < DISPLAY_WIDTH; x++) {
uint16_t pos = x + y * DISPLAY_WIDTH;
if (buffer[pos] != buffer_back[pos]) {
minBoundY = _min(minBoundY, y);
maxBoundY = _max(maxBoundY, y);
minBoundX = _min(minBoundX, x);
maxBoundX = _max(maxBoundX, x);
}
buffer_back[pos] = buffer[pos];
}
yield();
}
// If the minBoundY wasn't updated
// we can savely assume that buffer_back[pos] == buffer[pos]
// holdes true for all values of pos
if (minBoundY == ~0) return;
// Calculate the colum offset
uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F;
uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 );
for (y = minBoundY; y <= maxBoundY; y++) {
sendCommand(0xB0 + y);
sendCommand(minBoundXp2H);
sendCommand(minBoundXp2L);
digitalWrite(_dc, HIGH); // data mode
for (x = minBoundX; x <= maxBoundX; x++) {
SPI.transfer(buffer[x + y * DISPLAY_WIDTH]);
}
yield();
}
#else
for (uint8_t y=0; y<DISPLAY_HEIGHT/8; y++) {
sendCommand(0xB0 + y);
sendCommand(0x02);
sendCommand(0x10);
digitalWrite(_dc, HIGH); // data mode
for( uint8_t x=0; x < DISPLAY_WIDTH; x++) {
SPI.transfer(buffer[x + y * DISPLAY_WIDTH]);
}
yield();
}
#endif
}
private:
inline void sendCommand(uint8_t com) __attribute__((always_inline)){
digitalWrite(_dc, LOW);
SPI.transfer(com);
}
};
#endif
+152
View File
@@ -0,0 +1,152 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 by Daniel Eichhorn
* Copyright (c) 2016 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/
#ifndef SH1106Wire_h
#define SH1106Wire_h
#include "OLEDDisplay.h"
#include <Wire.h>
#define SH1106_SET_PUMP_VOLTAGE 0X30
#define SH1106_SET_PUMP_MODE 0XAD
#define SH1106_PUMP_ON 0X8B
#define SH1106_PUMP_OFF 0X8A
//--------------------------------------
class SH1106Wire : public OLEDDisplay {
private:
uint8_t _address;
uint8_t _sda;
uint8_t _scl;
public:
SH1106Wire(uint8_t _address, uint8_t _sda, uint8_t _scl) {
this->_address = _address;
this->_sda = _sda;
this->_scl = _scl;
}
bool connect() {
Wire.begin(this->_sda, this->_scl);
// Let's use ~700khz if ESP8266 is in 160Mhz mode
// this will be limited to ~400khz if the ESP8266 in 80Mhz mode.
Wire.setClock(700000);
return true;
}
void display(void) {
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
uint8_t minBoundY = ~0;
uint8_t maxBoundY = 0;
uint8_t minBoundX = ~0;
uint8_t maxBoundX = 0;
uint8_t x, y;
// Calculate the Y bounding box of changes
// and copy buffer[pos] to buffer_back[pos];
for (y = 0; y < (DISPLAY_HEIGHT / 8); y++) {
for (x = 0; x < DISPLAY_WIDTH; x++) {
uint16_t pos = x + y * DISPLAY_WIDTH;
if (buffer[pos] != buffer_back[pos]) {
minBoundY = _min(minBoundY, y);
maxBoundY = _max(maxBoundY, y);
minBoundX = _min(minBoundX, x);
maxBoundX = _max(maxBoundX, x);
}
buffer_back[pos] = buffer[pos];
}
yield();
}
// If the minBoundY wasn't updated
// we can savely assume that buffer_back[pos] == buffer[pos]
// holdes true for all values of pos
if (minBoundY == ~0) return;
// Calculate the colum offset
uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F;
uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 );
byte k = 0;
for (y = minBoundY; y <= maxBoundY; y++) {
sendCommand(0xB0 + y);
sendCommand(minBoundXp2H);
sendCommand(minBoundXp2L);
for (x = minBoundX; x <= maxBoundX; x++) {
if (k == 0) {
Wire.beginTransmission(_address);
Wire.write(0x40);
}
Wire.write(buffer[x + y * DISPLAY_WIDTH]);
k++;
if (k == 16) {
Wire.endTransmission();
k = 0;
}
}
if (k != 0) {
Wire.endTransmission();
k = 0;
}
yield();
}
if (k != 0) {
Wire.endTransmission();
}
#else
uint8_t * p = &buffer[0];
for (uint8_t y=0; y<8; y++) {
sendCommand(0xB0+y);
sendCommand(0x02);
sendCommand(0x10);
for( uint8_t x=0; x<8; x++) {
Wire.beginTransmission(_address);
Wire.write(0x40);
for (uint8_t k = 0; k < 16; k++) {
Wire.write(*p++);
}
Wire.endTransmission();
}
}
#endif
}
private:
inline void sendCommand(uint8_t command) __attribute__((always_inline)){
Wire.beginTransmission(_address);
Wire.write(0x80);
Wire.write(command);
Wire.endTransmission();
}
};
#endif
-363
View File
@@ -1,363 +0,0 @@
/**The MIT License (MIT)
Copyright (c) 2015 by Daniel Eichhorn
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
See more at http://blog.squix.ch
Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/
#include "../esp8266-oled-ssd1306/SSD1306.h"
#include <Wire.h>
SSD1306::SSD1306(int i2cAddress, int sda, int sdc) {
myI2cAddress = i2cAddress;
mySda = sda;
mySdc = sdc;
}
void SSD1306::init() {
Wire.begin(mySda, mySdc);
Wire.setClock(400000);
sendInitCommands();
resetDisplay();
}
// Local override of init to avoid having to pass the sda and sdc in global section.
void SSD1306::init(int i2cAddress) {
myI2cAddress = i2cAddress;
Wire.setClock(400000);
sendInitCommands();
resetDisplay();
}
void SSD1306::resetDisplay(void) {
displayOff();
clear();
display();
displayOn();
}
void SSD1306::reconnect() {
Wire.begin(mySda, mySdc);
}
void SSD1306::displayOn(void) {
sendCommand(0xaf); //display on
}
void SSD1306::displayOff(void) {
sendCommand(0xae); //display off
}
void SSD1306::setContrast(char contrast) {
sendCommand(0x81);
sendCommand(contrast);
}
void SSD1306::flipScreenVertically() {
sendCommand(0xA0 | 0x1); //SEGREMAP //Rotate screen 180 deg
sendCommand(0xC8); //COMSCANDEC Rotate screen 180 Deg
}
void SSD1306::clear(void) {
memset(buffer, 0, (128 * 64 / 8));
}
void SSD1306::display(void) {
sendCommand(COLUMNADDR);
sendCommand(0x0);
sendCommand(0x7F);
sendCommand(PAGEADDR);
sendCommand(0x0);
sendCommand(0x7);
for (uint16_t i=0; i<(128*64/8); i++) {
// send a bunch of data in one xmission
Wire.beginTransmission(myI2cAddress);
Wire.write(0x40);
for (uint8_t x=0; x<16; x++) {
Wire.write(buffer[i]);
i++;
}
i--;
yield();
Wire.endTransmission();
}
}
void SSD1306::setPixel(int x, int y) {
if (x >= 0 && x < 128 && y >= 0 && y < 64) {
switch (myColor) {
case WHITE: buffer[x + (y/8)*128] |= (1 << (y&7)); break;
case BLACK: buffer[x + (y/8)*128] &= ~(1 << (y&7)); break;
case INVERSE: buffer[x + (y/8)*128] ^= (1 << (y&7)); break;
}
}
}
void SSD1306::setChar(int x, int y, unsigned char data) {
for (int i = 0; i < 8; i++) {
if (bitRead(data, i)) {
setPixel(x,y + i);
}
}
}
// Code form http://playground.arduino.cc/Main/Utf8ascii
byte SSD1306::utf8ascii(byte ascii) {
if ( ascii<128 ) { // Standard ASCII-set 0..0x7F handling
lastChar=0;
return( ascii );
}
// get previous input
byte last = lastChar; // get last char
lastChar=ascii; // remember actual character
switch (last) // conversion depnding on first UTF8-character
{ case 0xC2: return (ascii); break;
case 0xC3: return (ascii | 0xC0); break;
case 0x82: if(ascii==0xAC) return(0x80); // special case Euro-symbol
}
return (0); // otherwise: return zero, if character has to be ignored
}
// Code form http://playground.arduino.cc/Main/Utf8ascii
String SSD1306::utf8ascii(String s) {
String r= "";
char c;
for (int i=0; i<s.length(); i++)
{
c = utf8ascii(s.charAt(i));
if (c!=0) r+=c;
}
return r;
}
void SSD1306::drawString(int x, int y, String text) {
text = utf8ascii(text);
unsigned char currentByte;
int charX, charY;
int currentBitCount;
int charCode;
int currentCharWidth;
int currentCharStartPos;
int cursorX = 0;
int numberOfChars = pgm_read_byte(myFontData + CHAR_NUM_POS);
// iterate over string
int firstChar = pgm_read_byte(myFontData + FIRST_CHAR_POS);
int charHeight = pgm_read_byte(myFontData + HEIGHT_POS);
int currentCharByteNum = 0;
int startX = 0;
int startY = y;
if (myTextAlignment == TEXT_ALIGN_LEFT) {
startX = x;
} else if (myTextAlignment == TEXT_ALIGN_CENTER) {
int width = getStringWidth(text);
startX = x - width / 2;
} else if (myTextAlignment == TEXT_ALIGN_RIGHT) {
int width = getStringWidth(text);
startX = x - width;
}
for (int j=0; j < text.length(); j++) {
charCode = text.charAt(j)-0x20;
currentCharWidth = pgm_read_byte(myFontData + CHAR_WIDTH_START_POS + charCode);
// Jump to font data beginning
currentCharStartPos = CHAR_WIDTH_START_POS + numberOfChars;
for (int m = 0; m < charCode; m++) {
currentCharStartPos += pgm_read_byte(myFontData + CHAR_WIDTH_START_POS + m) * charHeight / 8 + 1;
}
currentCharByteNum = ((charHeight * currentCharWidth) / 8) + 1;
// iterate over all bytes of character
for (int i = 0; i < currentCharByteNum; i++) {
currentByte = pgm_read_byte(myFontData + currentCharStartPos + i);
//Serial.println(String(charCode) + ", " + String(currentCharWidth) + ", " + String(currentByte));
// iterate over all bytes of character
for(int bit = 0; bit < 8; bit++) {
//int currentBit = bitRead(currentByte, bit);
currentBitCount = i * 8 + bit;
charX = currentBitCount % currentCharWidth;
charY = currentBitCount / currentCharWidth;
if (bitRead(currentByte, bit)) {
setPixel(startX + cursorX + charX, startY + charY);
}
}
yield();
}
cursorX += currentCharWidth;
}
}
void SSD1306::drawStringMaxWidth(int x, int y, int maxLineWidth, String text) {
int currentLineWidth = 0;
int startsAt = 0;
int endsAt = 0;
int lineNumber = 0;
char currentChar = ' ';
int lineHeight = pgm_read_byte(myFontData + HEIGHT_POS);
String currentLine = "";
for (int i = 0; i < text.length(); i++) {
currentChar = text.charAt(i);
if (currentChar == ' ' || currentChar == '-') {
String lineCandidate = text.substring(startsAt, i);
if (getStringWidth(lineCandidate) <= maxLineWidth) {
endsAt = i;
} else {
drawString(x, y + lineNumber * lineHeight, text.substring(startsAt, endsAt));
lineNumber++;
startsAt = endsAt + 1;
}
}
}
drawString(x, y + lineNumber * lineHeight, text.substring(startsAt));
}
int SSD1306::getStringWidth(String text) {
text = utf8ascii(text);
int stringWidth = 0;
char charCode;
for (int j=0; j < text.length(); j++) {
charCode = text.charAt(j)-0x20;
stringWidth += pgm_read_byte(myFontData + CHAR_WIDTH_START_POS + charCode);
}
return stringWidth;
}
void SSD1306::setTextAlignment(int textAlignment) {
myTextAlignment = textAlignment;
}
void SSD1306::setFont(const char *fontData) {
myFontData = fontData;
}
void SSD1306::drawBitmap(int x, int y, int width, int height, const char *bitmap) {
for (int i = 0; i < width * height / 8; i++ ){
unsigned char charColumn = 255 - pgm_read_byte(bitmap + i);
for (int j = 0; j < 8; j++) {
int targetX = i % width + x;
int targetY = (i / (width)) * 8 + j + y;
if (bitRead(charColumn, j)) {
setPixel(targetX, targetY);
}
}
}
}
void SSD1306::setColor(int color) {
myColor = color;
}
void SSD1306::drawRect(int x, int y, int width, int height) {
for (int i = x; i < x + width; i++) {
setPixel(i, y);
setPixel(i, y + height);
}
for (int i = y; i < y + height; i++) {
setPixel(x, i);
setPixel(x + width, i);
}
}
void SSD1306::fillRect(int x, int y, int width, int height) {
for (int i = x; i < x + width; i++) {
for (int j = y; j < y + height; j++) {
setPixel(i, j);
}
}
}
void SSD1306::drawXbm(int x, int y, int width, int height, const char *xbm) {
if (width % 8 != 0) {
width = ((width / 8) + 1) * 8;
}
for (int i = 0; i < width * height / 8; i++ ){
unsigned char charColumn = pgm_read_byte(xbm + i);
for (int j = 0; j < 8; j++) {
int targetX = (i * 8 + j) % width + x;
int targetY = (8 * i / (width)) + y;
if (bitRead(charColumn, j)) {
setPixel(targetX, targetY);
}
}
}
}
void SSD1306::sendCommand(unsigned char com) {
Wire.beginTransmission(myI2cAddress); //begin transmitting
Wire.write(0x80); //command mode
Wire.write(com);
Wire.endTransmission(); // stop transmitting
}
void SSD1306::sendInitCommands(void) {
sendCommand(DISPLAYOFF);
sendCommand(NORMALDISPLAY);
sendCommand(SETDISPLAYCLOCKDIV);
sendCommand(0x80);
sendCommand(SETMULTIPLEX);
sendCommand(0x3F);
sendCommand(SETDISPLAYOFFSET);
sendCommand(0x00);
sendCommand(SETSTARTLINE | 0x00);
sendCommand(CHARGEPUMP);
sendCommand(0x14);
sendCommand(MEMORYMODE);
sendCommand(0x00);
sendCommand(SEGREMAP);
sendCommand(COMSCANINC);
sendCommand(SETCOMPINS);
sendCommand(0x12);
sendCommand(SETCONTRAST);
sendCommand(0xCF);
sendCommand(SETPRECHARGE);
sendCommand(0xF1);
sendCommand(SETVCOMDETECT);
sendCommand(0x40);
sendCommand(DISPLAYALLON_RESUME);
sendCommand(NORMALDISPLAY);
sendCommand(0x2e); // stop scroll
sendCommand(DISPLAYON);
}
+32 -172
View File
@@ -1,176 +1,36 @@
/**The MIT License (MIT)
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 by Daniel Eichhorn
* Copyright (c) 2016 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/
Copyright (c) 2015 by Daniel Eichhorn
#ifndef SSD1306_h
#define SSD1306_h
#include "SSD1306Wire.h"
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
// For legacy support make SSD1306 an alias for SSD1306
typedef SSD1306Wire SSD1306;
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
See more at http://blog.squix.ch
Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/
#pragma once
#include <Arduino.h>
#include "SSD1306Fonts.h"
#define BLACK 0
#define WHITE 1
#define INVERSE 2
#define WIDTH_POS 0
#define HEIGHT_POS 1
#define FIRST_CHAR_POS 2
#define CHAR_NUM_POS 3
#define CHAR_WIDTH_START_POS 4
#define TEXT_ALIGN_LEFT 0
#define TEXT_ALIGN_CENTER 1
#define TEXT_ALIGN_RIGHT 2
#define CHARGEPUMP 0x8D
#define COLUMNADDR 0x21
#define COMSCANDEC 0xC8
#define COMSCANINC 0xC0
#define DISPLAYALLON 0xA5
#define DISPLAYALLON_RESUME 0xA4
#define DISPLAYOFF 0xAE
#define DISPLAYON 0xAF
#define EXTERNALVCC 0x1
#define INVERTDISPLAY 0xA7
#define MEMORYMODE 0x20
#define NORMALDISPLAY 0xA6
#define PAGEADDR 0x22
#define SEGREMAP 0xA0
#define SETCOMPINS 0xDA
#define SETCONTRAST 0x81
#define SETDISPLAYCLOCKDIV 0xD5
#define SETDISPLAYOFFSET 0xD3
#define SETHIGHCOLUMN 0x10
#define SETLOWCOLUMN 0x00
#define SETMULTIPLEX 0xA8
#define SETPRECHARGE 0xD9
#define SETSEGMENTREMAP 0xA1
#define SETSTARTLINE 0x40
#define SETVCOMDETECT 0xDB
#define SWITCHCAPVCC 0x2
class SSD1306 {
private:
int myI2cAddress;
int mySda;
int mySdc;
uint8_t buffer[128 * 64 / 8];
int myTextAlignment = TEXT_ALIGN_LEFT;
int myColor = WHITE;
byte lastChar;
const char *myFontData = ArialMT_Plain_10;
public:
// Create the display object connected to pin sda and sdc
SSD1306(int i2cAddress, int sda, int sdc);
// Initialize the display
void init();
// Initialize the display - Neil's version to setting of address
void init(int i2cAddress); //local override to allow init to set the address
// Cycle through the initialization
void resetDisplay(void);
// Connect again to the display through I2C
void reconnect(void);
// Turn the display on
void displayOn(void);
// Turn the display offs
void displayOff(void);
// Clear the local pixel buffer
void clear(void);
// Write the buffer to the display memory
void display(void);
// Set display contrast
void setContrast(char contrast);
// Turn the display upside down
void flipScreenVertically();
// Send a command to the display (low level function)
void sendCommand(unsigned char com);
// Send all the init commands
void sendInitCommands(void);
// Draw a pixel at given position
void setPixel(int x, int y);
// Draw 8 bits at the given position
void setChar(int x, int y, unsigned char data);
// Draw the border of a rectangle at the given location
void drawRect(int x, int y, int width, int height);
// Fill the rectangle
void fillRect(int x, int y, int width, int height);
// Draw a bitmap with the given dimensions
void drawBitmap(int x, int y, int width, int height, const char *bitmap);
// Draw an XBM image with the given dimensions
void drawXbm(int x, int y, int width, int height, const char *xbm);
// Sets the color of all pixel operations
void setColor(int color);
// converts utf8 characters to extended ascii
// taken from http://playground.arduino.cc/Main/Utf8ascii
byte utf8ascii(byte ascii);
// converts utf8 string to extended ascii
// taken from http://playground.arduino.cc/Main/Utf8ascii
String utf8ascii(String s);
// Draws a string at the given location
void drawString(int x, int y, String text);
// Draws a String with a maximum width at the given location.
// If the given String is wider than the specified width
// The text will be wrapped to the next line at a space or dash
void drawStringMaxWidth(int x, int y, int maxLineWidth, String text);
// Returns the width of the String with the current
// font settings
int getStringWidth(String text);
// Specifies relative to which anchor point
// the text is rendered. Available constants:
// TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT
void setTextAlignment(int textAlignment);
// Sets the current font. Available default fonts
// defined in SSD1306Fonts.h:
// ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24
void setFont(const char *fontData);
};
#endif
+149
View File
@@ -0,0 +1,149 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 by Daniel Eichhorn
* Copyright (c) 2016 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/
#ifndef SSD1306Brzo_h
#define SSD1306Brzo_h
#include "OLEDDisplay.h"
#include <brzo_i2c.h>
#if F_CPU == 160000000L
#define BRZO_I2C_SPEED 1000
#else
#define BRZO_I2C_SPEED 800
#endif
class SSD1306Brzo : public OLEDDisplay {
private:
uint8_t _address;
uint8_t _sda;
uint8_t _scl;
public:
SSD1306Brzo(uint8_t _address, uint8_t _sda, uint8_t _scl) {
this->_address = _address;
this->_sda = _sda;
this->_scl = _scl;
}
bool connect(){
brzo_i2c_setup(_sda, _scl, 0);
return true;
}
void display(void) {
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
uint8_t minBoundY = ~0;
uint8_t maxBoundY = 0;
uint8_t minBoundX = ~0;
uint8_t maxBoundX = 0;
uint8_t x, y;
// Calculate the Y bounding box of changes
// and copy buffer[pos] to buffer_back[pos];
for (y = 0; y < (DISPLAY_HEIGHT / 8); y++) {
for (x = 0; x < DISPLAY_WIDTH; x++) {
uint16_t pos = x + y * DISPLAY_WIDTH;
if (buffer[pos] != buffer_back[pos]) {
minBoundY = _min(minBoundY, y);
maxBoundY = _max(maxBoundY, y);
minBoundX = _min(minBoundX, x);
maxBoundX = _max(maxBoundX, x);
}
buffer_back[pos] = buffer[pos];
}
yield();
}
// If the minBoundY wasn't updated
// we can savely assume that buffer_back[pos] == buffer[pos]
// holdes true for all values of pos
if (minBoundY == ~0) return;
sendCommand(COLUMNADDR);
sendCommand(minBoundX);
sendCommand(maxBoundX);
sendCommand(PAGEADDR);
sendCommand(minBoundY);
sendCommand(maxBoundY);
byte k = 0;
uint8_t sendBuffer[17];
sendBuffer[0] = 0x40;
brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED);
for (y = minBoundY; y <= maxBoundY; y++) {
for (x = minBoundX; x <= maxBoundX; x++) {
k++;
sendBuffer[k] = buffer[x + y * DISPLAY_WIDTH];
if (k == 16) {
brzo_i2c_write(sendBuffer, 17, true);
k = 0;
}
}
yield();
}
brzo_i2c_write(sendBuffer, k + 1, true);
brzo_i2c_end_transaction();
#else
// No double buffering
sendCommand(COLUMNADDR);
sendCommand(0x0);
sendCommand(0x7F);
sendCommand(PAGEADDR);
sendCommand(0x0);
sendCommand(0x7);
uint8_t sendBuffer[17];
sendBuffer[0] = 0x40;
brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED);
for (uint16_t i=0; i<DISPLAY_BUFFER_SIZE; i++) {
for (uint8_t x=1; x<17; x++) {
sendBuffer[x] = buffer[i];
i++;
}
i--;
brzo_i2c_write(sendBuffer, 17, true);
yield();
}
brzo_i2c_end_transaction();
#endif
}
private:
inline void sendCommand(uint8_t com) __attribute__((always_inline)){
uint8_t command[2] = {0x80 /* command mode */, com};
brzo_i2c_start_transaction(_address, BRZO_I2C_SPEED);
brzo_i2c_write(command, 2, true);
brzo_i2c_end_transaction();
}
};
#endif
File diff suppressed because it is too large Load Diff
+150
View File
@@ -0,0 +1,150 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 by Daniel Eichhorn
* Copyright (c) 2016 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/
#ifndef SSD1306Spi_h
#define SSD1306Spi_h
#include "OLEDDisplay.h"
#include <SPI.h>
#if F_CPU == 160000000L
#define BRZO_I2C_SPEED 1000
#else
#define BRZO_I2C_SPEED 800
#endif
class SSD1306Spi : public OLEDDisplay {
private:
uint8_t _rst;
uint8_t _dc;
uint8_t _cs;
public:
SSD1306Spi(uint8_t _rst, uint8_t _dc, uint8_t _cs) {
this->_rst = _rst;
this->_dc = _dc;
this->_cs = _cs;
}
bool connect(){
pinMode(_dc, OUTPUT);
pinMode(_cs, OUTPUT);
pinMode(_rst, OUTPUT);
SPI.begin ();
SPI.setClockDivider (SPI_CLOCK_DIV2);
// Pulse Reset low for 10ms
digitalWrite(_rst, HIGH);
delay(1);
digitalWrite(_rst, LOW);
delay(10);
digitalWrite(_rst, HIGH);
return true;
}
void display(void) {
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
uint8_t minBoundY = ~0;
uint8_t maxBoundY = 0;
uint8_t minBoundX = ~0;
uint8_t maxBoundX = 0;
uint8_t x, y;
// Calculate the Y bounding box of changes
// and copy buffer[pos] to buffer_back[pos];
for (y = 0; y < (DISPLAY_HEIGHT / 8); y++) {
for (x = 0; x < DISPLAY_WIDTH; x++) {
uint16_t pos = x + y * DISPLAY_WIDTH;
if (buffer[pos] != buffer_back[pos]) {
minBoundY = _min(minBoundY, y);
maxBoundY = _max(maxBoundY, y);
minBoundX = _min(minBoundX, x);
maxBoundX = _max(maxBoundX, x);
}
buffer_back[pos] = buffer[pos];
}
yield();
}
// If the minBoundY wasn't updated
// we can savely assume that buffer_back[pos] == buffer[pos]
// holdes true for all values of pos
if (minBoundY == ~0) return;
sendCommand(COLUMNADDR);
sendCommand(minBoundX);
sendCommand(maxBoundX);
sendCommand(PAGEADDR);
sendCommand(minBoundY);
sendCommand(maxBoundY);
digitalWrite(_cs, HIGH);
digitalWrite(_dc, HIGH); // data mode
digitalWrite(_cs, LOW);
for (y = minBoundY; y <= maxBoundY; y++) {
for (x = minBoundX; x <= maxBoundX; x++) {
SPI.transfer(buffer[x + y * DISPLAY_WIDTH]);
}
yield();
}
digitalWrite(_cs, HIGH);
#else
// No double buffering
sendCommand(COLUMNADDR);
sendCommand(0x0);
sendCommand(0x7F);
sendCommand(PAGEADDR);
sendCommand(0x0);
sendCommand(0x7);
digitalWrite(_cs, HIGH);
digitalWrite(_dc, HIGH); // data mode
digitalWrite(_cs, LOW);
for (uint16_t i=0; i<DISPLAY_BUFFER_SIZE; i++) {
SPI.transfer(buffer[i]);
yield();
}
digitalWrite(_cs, HIGH);
#endif
}
private:
inline void sendCommand(uint8_t com) __attribute__((always_inline)){
digitalWrite(_cs, HIGH);
digitalWrite(_dc, LOW);
digitalWrite(_cs, LOW);
SPI.transfer(com);
digitalWrite(_cs, HIGH);
}
};
#endif
-247
View File
@@ -1,247 +0,0 @@
#include "SSD1306Ui.h"
SSD1306Ui::SSD1306Ui(SSD1306 *display) {
this->display = display;
}
void SSD1306Ui::init() {
this->display->init();
}
void SSD1306Ui::setTargetFPS(byte fps){
int oldInterval = this->updateInterval;
this->updateInterval = ((float) 1.0 / (float) fps) * 1000;
// Calculate new ticksPerFrame
float changeRatio = oldInterval / this->updateInterval;
this->ticksPerFrame *= changeRatio;
this->ticksPerTransition *= changeRatio;
}
// -/------ Automatic controll ------\-
void SSD1306Ui::enableAutoTransition(){
this->autoTransition = true;
}
void SSD1306Ui::disableAutoTransition(){
this->autoTransition = false;
}
void SSD1306Ui::setAutoTransitionForwards(){
this->frameTransitionDirection = 1;
}
void SSD1306Ui::setAutoTransitionBackwards(){
this->frameTransitionDirection = 1;
}
void SSD1306Ui::setTimePerFrame(int time){
this->ticksPerFrame = (int) ( (float) time / (float) updateInterval);
}
void SSD1306Ui::setTimePerTransition(int time){
this->ticksPerTransition = (int) ( (float) time / (float) updateInterval);
}
// -/------ Customize indicator position and style -------\-
void SSD1306Ui::setIndicatorPosition(IndicatorPosition pos) {
this->indicatorPosition = pos;
this->dirty = true;
}
void SSD1306Ui::setIndicatorDirection(IndicatorDirection dir) {
this->indicatorDirection = dir;
}
void SSD1306Ui::setActiveSymbole(const char* symbole) {
this->activeSymbole = symbole;
this->dirty = true;
}
void SSD1306Ui::setInactiveSymbole(const char* symbole) {
this->inactiveSymbole = symbole;
this->dirty = true;
}
// -/----- Frame settings -----\-
void SSD1306Ui::setFrameAnimation(AnimationDirection dir) {
this->frameAnimationDirection = dir;
}
void SSD1306Ui::setFrames(FrameCallback* frameFunctions, int frameCount) {
this->frameCount = frameCount;
this->frameFunctions = frameFunctions;
}
// -/----- Overlays ------\-
void SSD1306Ui::setOverlays(OverlayCallback* overlayFunctions, int overlayCount){
this->overlayCount = overlayCount;
this->overlayFunctions = overlayFunctions;
}
// -/----- Manuel control -----\-
void SSD1306Ui::nextFrame() {
this->state.frameState = IN_TRANSITION;
this->state.ticksSinceLastStateSwitch = 0;
this->frameTransitionDirection = 1;
}
void SSD1306Ui::previousFrame() {
this->state.frameState = IN_TRANSITION;
this->state.ticksSinceLastStateSwitch = 0;
this->frameTransitionDirection = -1;
}
// -/----- State information -----\-
SSD1306UiState SSD1306Ui::getUiState(){
return this->state;
}
int SSD1306Ui::update(){
int timeBudget = this->updateInterval - (millis() - this->state.lastUpdate);
if ( timeBudget <= 0) {
// Implement frame skipping to ensure time budget is keept
if (this->autoTransition && this->state.lastUpdate != 0) this->state.ticksSinceLastStateSwitch += ceil(-timeBudget / this->updateInterval);
this->state.lastUpdate = millis();
this->tick();
}
return timeBudget;
}
void SSD1306Ui::tick() {
this->state.ticksSinceLastStateSwitch++;
switch (this->state.frameState) {
case IN_TRANSITION:
this->dirty = true;
if (this->state.ticksSinceLastStateSwitch >= this->ticksPerTransition){
this->state.frameState = FIXED;
this->state.currentFrame = getNextFrameNumber();
this->state.ticksSinceLastStateSwitch = 0;
}
break;
case FIXED:
if (this->state.ticksSinceLastStateSwitch >= this->ticksPerFrame){
if (this->autoTransition){
this->state.frameState = IN_TRANSITION;
this->dirty = true;
}
this->state.ticksSinceLastStateSwitch = 0;
}
break;
}
if (this->dirty) {
this->dirty = false;
this->display->clear();
this->drawIndicator();
this->drawFrame();
this->drawOverlays();
this->display->display();
}
}
void SSD1306Ui::drawFrame(){
switch (this->state.frameState){
case IN_TRANSITION: {
float progress = (float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition;
int x, y, x1, y1;
switch(this->frameAnimationDirection){
case SLIDE_LEFT:
x = -128 * progress;
y = 0;
x1 = x + 128;
y1 = 0;
break;
case SLIDE_RIGHT:
x = 128 * progress;
y = 0;
x1 = x - 128;
y1 = 0;
break;
case SLIDE_UP:
x = 0;
y = -64 * progress;
x1 = 0;
y1 = y + 64;
break;
case SLIDE_DOWN:
x = 0;
y = 64 * progress;
x1 = 0;
y1 = y - 64;
break;
}
// Invert animation if direction is reversed.
int dir = frameTransitionDirection >= 0 ? 1 : -1;
x *= dir; y *= dir; x1 *= dir; y1 *= dir;
this->dirty |= (this->frameFunctions[this->state.currentFrame])(this->display, &this->state, x, y);
this->dirty |= (this->frameFunctions[this->getNextFrameNumber()])(this->display, &this->state, x1, y1);
break;
}
case FIXED:
this->dirty |= (this->frameFunctions[this->state.currentFrame])(this->display, &this->state, 0, 0);
break;
}
}
void SSD1306Ui::drawIndicator() {
byte posOfCurrentFrame;
switch (this->indicatorDirection){
case LEFT_RIGHT:
posOfCurrentFrame = this->state.currentFrame;
break;
case RIGHT_LEFT:
posOfCurrentFrame = (this->frameCount - 1) - this->state.currentFrame;
break;
}
for (byte i = 0; i < this->frameCount; i++) {
const char *image;
if (posOfCurrentFrame == i) {
image = this->activeSymbole;
} else {
image = this->inactiveSymbole;
}
int x,y;
switch (this->indicatorPosition){
case TOP:
y = 0;
x = 64 - (12 * frameCount / 2) + 12 * i;
break;
case BOTTOM:
y = 56;
x = 64 - (12 * frameCount / 2) + 12 * i;
break;
case RIGHT:
x = 120;
y = 32 - (12 * frameCount / 2) + 12 * i;
break;
case LEFT:
x = 0;
y = 32 - (12 * frameCount / 2) + 12 * i;
break;
}
this->display->drawXbm(x, y, 8, 8, image);
}
}
void SSD1306Ui::drawOverlays() {
for (int i=0;i<this->overlayCount;i++){
this->dirty |= (this->overlayFunctions[i])(this->display, &this->state);
}
}
int SSD1306Ui::getNextFrameNumber(){
int nextFrame = (this->state.currentFrame + this->frameTransitionDirection) % this->frameCount;
if (nextFrame < 0){
nextFrame = this->frameCount + nextFrame;
}
return nextFrame;
}
-209
View File
@@ -1,209 +0,0 @@
/**The MIT License (MIT)
Copyright (c) 2015 by Fabrice Weinberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Credits for parts of this code go to Daniel Eichhorn
*/
#pragma once
#include <Arduino.h>
#include "../esp8266-oled-ssd1306/SSD1306.h"
enum AnimationDirection {
SLIDE_UP,
SLIDE_DOWN,
SLIDE_LEFT,
SLIDE_RIGHT
};
enum IndicatorPosition {
TOP,
RIGHT,
BOTTOM,
LEFT
};
enum IndicatorDirection {
LEFT_RIGHT,
RIGHT_LEFT
};
enum FrameState {
IN_TRANSITION,
FIXED
};
const char ANIMATION_activeSymbole[] PROGMEM = {
0x00, 0x18, 0x3c, 0x7e, 0x7e, 0x3c, 0x18, 0x00
};
const char ANIMATION_inactiveSymbole[] PROGMEM = {
0x00, 0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x00
};
// Structure of the UiState
struct SSD1306UiState {
int lastUpdate = 0;
int ticksSinceLastStateSwitch = 0;
FrameState frameState = FIXED;
int currentFrame = 0;
};
typedef bool (*FrameCallback)(SSD1306 *display, SSD1306UiState* state, int x, int y);
typedef bool (*OverlayCallback)(SSD1306 *display, SSD1306UiState* state);
class SSD1306Ui {
private:
SSD1306 *display;
// Global dirty flag to indicate that the display needs to be redraw.
bool dirty = true;
// Symboles for the Indicator
IndicatorPosition indicatorPosition = BOTTOM;
IndicatorDirection indicatorDirection = LEFT_RIGHT;
const char* activeSymbole = ANIMATION_activeSymbole;
const char* inactiveSymbole = ANIMATION_inactiveSymbole;
// Values for the Frames
AnimationDirection frameAnimationDirection = SLIDE_RIGHT;
int frameTransitionDirection = 1;
int ticksPerFrame = 151; // ~ 5000ms at 30 FPS
int ticksPerTransition = 15; // ~ 500ms at 30 FPS
bool autoTransition = true;
FrameCallback* frameFunctions;
int frameCount = 0;
// Values for Overlays
OverlayCallback* overlayFunctions;
int overlayCount = 0;
// UI State
SSD1306UiState state;
// Bookeeping for update
int updateInterval = 33;
int getNextFrameNumber();
void drawIndicator();
void drawFrame();
void drawOverlays();
void tick();
public:
SSD1306Ui(SSD1306 *display);
/**
* Initialise the display
*/
void init();
/**
* Configure the internal used target FPS
*/
void setTargetFPS(byte fps);
// Automatic Controll
/**
* Enable automatic transition to next frame after the some time can be configured with `setTimePerFrame` and `setTimePerTransition`.
*/
void enableAutoTransition();
/**
* Disable automatic transition to next frame.
*/
void disableAutoTransition();
/**
* Set the direction if the automatic transitioning
*/
void setAutoTransitionForwards();
void setAutoTransitionBackwards();
/**
* Set the approx. time a frame is displayed
*/
void setTimePerFrame(int time);
/**
* Set the approx. time a transition will take
*/
void setTimePerTransition(int time);
// Customize indicator position and style
/**
* Set the position of the indicator bar.
*/
void setIndicatorPosition(IndicatorPosition pos);
/**
* Set the direction of the indicator bar. Defining the order of frames ASCENDING / DESCENDING
*/
void setIndicatorDirection(IndicatorDirection dir);
/**
* Set the symbole to indicate an active frame in the indicator bar.
*/
void setActiveSymbole(const char* symbole);
/**
* Set the symbole to indicate an inactive frame in the indicator bar.
*/
void setInactiveSymbole(const char* symbole);
// Frame settings
/**
* Configure what animation is used to transition from one frame to another
*/
void setFrameAnimation(AnimationDirection dir);
/**
* Add frame drawing functions
*/
void setFrames(FrameCallback* frameFunctions, int frameCount);
// Overlay
/**
* Add overlays drawing functions that are draw independent of the Frames
*/
void setOverlays(OverlayCallback* overlayFunctions, int overlayCount);
// Manuell Controll
void nextFrame();
void previousFrame();
// State Info
SSD1306UiState getUiState();
int update();
};
+149
View File
@@ -0,0 +1,149 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 by Daniel Eichhorn
* Copyright (c) 2016 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
*/
#ifndef SSD1306Wire_h
#define SSD1306Wire_h
#include "OLEDDisplay.h"
#include <Wire.h>
class SSD1306Wire : public OLEDDisplay {
private:
uint8_t _address;
uint8_t _sda;
uint8_t _scl;
public:
SSD1306Wire(uint8_t _address, uint8_t _sda, uint8_t _scl, int width = DISPLAY_WIDTH, int height = DISPLAY_HEIGHT)
: OLEDDisplay(width, height) {
this->_address = _address;
this->_sda = _sda;
this->_scl = _scl;
}
bool connect() {
Wire.begin(this->_sda, this->_scl);
// Let's use ~700khz if ESP8266 is in 160Mhz mode
// this will be limited to ~400khz if the ESP8266 in 80Mhz mode.
Wire.setClock(700000);
return true;
}
void display(void) {
const int x_offset = (128 - this->width()) / 2;
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
uint8_t minBoundY = ~0;
uint8_t maxBoundY = 0;
uint8_t minBoundX = ~0;
uint8_t maxBoundX = 0;
uint8_t x, y;
// Calculate the Y bounding box of changes
// and copy buffer[pos] to buffer_back[pos];
for (y = 0; y < (this->height() / 8); y++) {
for (x = 0; x < this->width(); x++) {
uint16_t pos = x + y * this->width();
if (buffer[pos] != buffer_back[pos]) {
minBoundY = _min(minBoundY, y);
maxBoundY = _max(maxBoundY, y);
minBoundX = _min(minBoundX, x);
maxBoundX = _max(maxBoundX, x);
}
buffer_back[pos] = buffer[pos];
}
yield();
}
// If the minBoundY wasn't updated
// we can savely assume that buffer_back[pos] == buffer[pos]
// holdes true for all values of pos
if (minBoundY == (uint8_t)(~0)) return;
sendCommand(COLUMNADDR);
sendCommand(x_offset + minBoundX);
sendCommand(x_offset + maxBoundX);
sendCommand(PAGEADDR);
sendCommand(minBoundY);
sendCommand(maxBoundY);
byte k = 0;
for (y = minBoundY; y <= maxBoundY; y++) {
for (x = minBoundX; x <= maxBoundX; x++) {
if (k == 0) {
Wire.beginTransmission(_address);
Wire.write(0x40);
}
Wire.write(buffer[x + y * this->width()]);
k++;
if (k == 16) {
Wire.endTransmission();
k = 0;
}
}
yield();
}
if (k != 0) {
Wire.endTransmission();
}
#else
sendCommand(COLUMNADDR);
sendCommand(x_offset);
sendCommand(x_offset + (this->width() - 1));
sendCommand(PAGEADDR);
sendCommand(0x0);
sendCommand((this->height() / 8) - 1);
for (uint16_t i=0; i < DISPLAY_BUFFER_SIZE; i++) {
Wire.beginTransmission(this->_address);
Wire.write(0x40);
for (uint8_t x = 0; x < 16; x++) {
Wire.write(buffer[i]);
i++;
}
i--;
Wire.endTransmission();
}
#endif
}
private:
inline void sendCommand(uint8_t command) __attribute__((always_inline)){
Wire.beginTransmission(_address);
Wire.write(0x80);
Wire.write(command);
Wire.endTransmission();
}
};
#endif
+125
View File
@@ -0,0 +1,125 @@
# Upgrade from 2.0 to 3.0
While developing version 3.0 we made some breaking changes to the public
API of this library. This document will help you update your code to work with
version 3.0
## Font Definitions
To get better performance and a smaller font definition format, we change the memory
layout of the font definition format. If you are using custom fonts not included in
this library we updated the font generator [here](http://oleddisplay.squix.ch/#/home).
Please update your fonts to be working with 3.0 by selecting the respective version in the dropdown.
## Architectural Changes
To become a more versatile library for the SSD1306 chipset we abstracted the
hardware connection into subclasses of the base display class now called `OLEDDisplay`.
This library is currently shipping with three implementations:
* `SSD1306Wire` implementing the I2C protocol using the Wire Library.
* `SSD1306Brzo` implementing the I2C protocol using the faster [`brzo_i2c`](https://github.com/pasko-zh/brzo_i2c) library.
* `SSD1306Spi` implementing the SPI protocol.
To keep backwards compatiblity with the old API `SSD1306` is an alias of `SSD1306Wire`.
If you are not using the UI components you don't have to change anything to keep your code working.
## Name Changes
[Naming things is hard](http://martinfowler.com/bliki/TwoHardThings.html), to better reflect our intention with this library
we changed the name of the base class to `OLEDDisplay` and the UI library accordingly to `OLEDDisplayUi`.
As a consequence the type definitions of all frame and overlay related functions changed.
This means that you have to update all your frame drawing callbacks from:
```c
bool frame1(SSD1306 *display, SSD1306UiState* state, int x, int y);
```
too
```c
void frame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
```
And your overlay drawing functions from:
```c
bool overlay1(SSD1306 *display, SSD1306UiState* state);
```
too
```c
void overlay1(OLEDDisplay *display, OLEDDisplayUiState* state);
```
## New Features
### Loading Animation
While using this library ourself we noticed a pattern emerging. We want to drawing
a loading progress while connecting to WiFi and updating weather data etc.
The simplest thing was to add the function `drawProgressBar(x, y, width, height, progress)`
,where `progress` is between `0` and `100`, right to the `OLEDDisplay` class.
But we didn't stop there. We added a new feature to the `OLEDDisplayUi` called `LoadingStages`.
You can define your loading process like this:
```c++
LoadingStage loadingStages[] = {
{
.process = "Connect to WiFi",
.callback = []() {
// Connect to WiFi
}
},
{
.process = "Get time from NTP",
.callback = []() {
// Get current time via NTP
}
}
// more steps
};
int LOADING_STAGES_COUNT = sizeof(loadingStages) / sizeof(LoadingStage);
```
After defining your array of `LoadingStages` you can then run the loading process by using
`ui.runLoadingProcess(loadingStages, LOADING_STAGES_COUNT)`. This will give you a
nice little loading animation you can see in the beginning of [this](https://vimeo.com/168362918)
video.
To further customize this you are free to define your own `LoadingDrawFunction` like this:
```c
void myLoadingDraw(OLEDDisplay *display, LoadingStage* stage, uint8_t progress) {
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(ArialMT_Plain_10);
// stage->process contains the text of the current progress e.q. "Connect to WiFi"
display->drawString(64, 18, stage->process);
// you could just print the current process without the progress bar
display->drawString(64, 28, progress);
}
```
After defining a function like that, you can pass it to the Ui library by use
`ui.setLoadingDrawFunction(myLoadingDraw)`.
### Text Logging
It is always useful to display some text on the display without worrying to much
where it goes and managing it. In 3.0 we made the `OLEDDisplay` class implement
[`Print`](https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/Print.h)
so you can use it like you would use `Serial`. We calls this feature `LogBuffer`
and the only thing you have to do is to define how many lines you want to display
and how many characters there are on average on each. This is done by calling
`setLogBuffer(lines, chars);`. If there is not enough memory the function will
return false.
After that you can draw the `LogBuffer` anywhere you want by calling `drawLogBuffer(x, y)`.
(Note: You have to call `display()` to update the screen)
We made a [video](https://www.youtube.com/watch?v=8Fiss77A3TE) showing this feature in action.
@@ -1,151 +0,0 @@
/**The MIT License (MIT)
Copyright (c) 2015 by Daniel Eichhorn
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
See more at http://blog.squix.ch
*/
#include <Wire.h>
#include "SSD1306.h"
#include "SSD1306Ui.h"
#include "images.h"
// Initialize the oled display for address 0x3c
// sda-pin=14 and sdc-pin=12
SSD1306 display(0x3c, D3, D4);
SSD1306Ui ui ( &display );
// this array keeps function pointers to all frames
// frames are the single views that slide from right to left
bool (*frames[])(SSD1306 *display, SSD1306UiState* state, int x, int y) = { drawFrame1, drawFrame2, drawFrame3, drawFrame4 };
// how many frames are there?
int frameCount = 4;
bool (*overlays[])(SSD1306 *display, SSD1306UiState* state) = { msOverlay };
int overlaysCount = 1;
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();
ui.setTargetFPS(30);
ui.setActiveSymbole(activeSymbole);
ui.setInactiveSymbole(inactiveSymbole);
// You can change this to
// TOP, LEFT, BOTTOM, RIGHT
ui.setIndicatorPosition(BOTTOM);
// Defines where the first frame is located in the bar.
ui.setIndicatorDirection(LEFT_RIGHT);
// You can change the transition that is used
// SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN
ui.setFrameAnimation(SLIDE_LEFT);
// Add frames
ui.setFrames(frames, frameCount);
// Add overlays
ui.setOverlays(overlays, overlaysCount);
// Inital UI takes care of initalising the display too.
ui.init();
display.flipScreenVertically();
}
void loop() {
int remainingTimeBudget = ui.update();
if (remainingTimeBudget > 0) {
// You can do some work here
// Don't do stuff if you are below your
// time budget.
delay(remainingTimeBudget);
}
}
bool msOverlay(SSD1306 *display, SSD1306UiState* state) {
display->setTextAlignment(TEXT_ALIGN_RIGHT);
display->setFont(ArialMT_Plain_10);
display->drawString(128, 0, String(millis()));
return true;
}
bool drawFrame1(SSD1306 *display, SSD1306UiState* state, int x, int y) {
// draw an xbm image.
// Please note that everything that should be transitioned
// needs to be drawn relative to x and y
// if this frame need to be refreshed at the targetFPS you need to
// return true
display->drawXbm(x + 34, y + 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits);
return false;
}
bool drawFrame2(SSD1306 *display, SSD1306UiState* state, int x, int y) {
// Demonstrates the 3 included default sizes. The fonts come from SSD1306Fonts.h file
// Besides the default fonts there will be a program to convert TrueType fonts into this format
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_10);
display->drawString(0 + x, 10 + y, "Arial 10");
display->setFont(ArialMT_Plain_16);
display->drawString(0 + x, 20 + y, "Arial 16");
display->setFont(ArialMT_Plain_24);
display->drawString(0 + x, 34 + y, "Arial 24");
return false;
}
bool drawFrame3(SSD1306 *display, SSD1306UiState* state, int x, int y) {
// Text alignment demo
display->setFont(ArialMT_Plain_10);
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(0 + x, 11 + y, "Left aligned (0,10)");
// The coordinates define the center of the text
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->drawString(64 + x, 22, "Center aligned (64,22)");
// The coordinates define the right end of the text
display->setTextAlignment(TEXT_ALIGN_RIGHT);
display->drawString(128 + x, 33, "Right aligned (128,33)");
return false;
}
bool drawFrame4(SSD1306 *display, SSD1306UiState* state, int x, int y) {
// Demo for drawStringMaxWidth:
// with the third parameter you can define the width after which words will be wrapped.
// Currently only spaces and "-" are allowed for wrapping
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_10);
display->drawStringMaxWidth(0 + x, 10 + y, 128, "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore.");
return false;
}
@@ -1,50 +0,0 @@
#define WiFi_Logo_width 60
#define WiFi_Logo_height 36
const char WiFi_Logo_bits[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF,
0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00,
0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C,
0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00,
0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C,
0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00,
0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C,
0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00,
0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C,
0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00,
0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F,
0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00,
0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF,
0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00,
0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const char activeSymbole[] PROGMEM = {
B00000000,
B00000000,
B00011000,
B00100100,
B01000010,
B01000010,
B00100100,
B00011000
};
const char inactiveSymbole[] PROGMEM = {
B00000000,
B00000000,
B00000000,
B00000000,
B00011000,
B00011000,
B00000000,
B00000000
};
-51
View File
@@ -1,51 +0,0 @@
#define WiFi_Logo_width 60
#define WiFi_Logo_height 36
const char WiFi_Logo_bits[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF,
0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00,
0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C,
0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00,
0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C,
0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00,
0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C,
0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00,
0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C,
0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00,
0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F,
0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00,
0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF,
0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00,
0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const char activeSymbole[] PROGMEM = {
B00000000,
B00000000,
B00011000,
B00100100,
B01000010,
B01000010,
B00100100,
B00011000
};
const char inactiveSymbole[] PROGMEM = {
B00000000,
B00000000,
B00000000,
B00000000,
B00011000,
B00011000,
B00000000,
B00000000
};
+21 -15
View File
@@ -1,22 +1,28 @@
{
"name": "ESP8266 Oled Driver for SSD1306 display",
"keywords": "Display, ssd1306, arduino, esp8266",
"description": "SSD1306 Oled driver which offers scrolling frames, custom fonts, etc",
"repository": {
"name": "ESP8266_SSD1306",
"version": "3.2.7",
"keywords": "ssd1306, oled, display, i2c",
"description": "A I2C display driver for SSD1306 oled displays connected to an ESP8266 or ESP32",
"repository":
{
"type": "git",
"url": "https://github.com/squix78/esp8266-oled-ssd1306.git"
},
"authors": [{
"name": "Daniel Eichhorn",
"url": "http://blog.squix.ch",
"email": "squix78@gmail.com",
"maintainer": true
},
{
"name": "Fabrice Weinberg"
}
"authors":
[
{
"name": "Daniel Eichhorn",
"email": "squix78@gmail.com",
"url": "http://blog.squix.ch"
},
{
"name": "Fabrice Weinberg",
"email": "fabrice@weinberg.me"
}
],
"frameworks": "arduino",
"platforms": "espressif",
"version": "2.0.1"
"platforms": [
"espressif8266",
"espressif32"
]
}
+5 -5
View File
@@ -1,9 +1,9 @@
name=ESP8266 Oled Driver for SSD1306 display
version=2.0.0
name=ESP8266 and ESP32 Oled Driver for SSD1306 display
version=3.2.7
author=Daniel Eichhorn, Fabrice Weinberg
maintainer=Daniel Eichhorn <squix78@gmail.com>
sentence=A display driver for SSD1306 oled displays connected to an ESP8266
paragraph=A display driver for SSD1306 oled displays connected to an ESP8266
sentence=A I2C display driver for SSD1306 oled displays connected to an ESP8266 or ESP32
paragraph=A I2C display driver for SSD1306 oled displays connected to an ESP8266 or ESP32
category=Display
url=https://github.com/squix78/esp8266-oled-ssd1306
architectures=esp8266
architectures=esp8266,esp32
+2 -1
View File
@@ -1,6 +1,7 @@
The MIT License (MIT)
Copyright (c) 2015 by Daniel Eichhorn
Copyright (c) 2016 by Daniel Eichhorn
Copyright (c) 2016 by Fabrice Weinberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

+3 -3
View File
@@ -244,7 +244,7 @@ uint16_t PubSubClient::readPacket(uint8_t* lengthLength) {
buffer[len++] = digit;
length += (digit & 127) * multiplier;
multiplier *= 128;
} while ((digit & 128) != 0);
} while ((digit & 128) != 0 && len < (MQTT_MAX_PACKET_SIZE -2));
*lengthLength = len-1;
if (isPublish) {
@@ -420,7 +420,7 @@ boolean PubSubClient::publish_P(const char* topic, const uint8_t* payload, unsig
lastOutActivity = millis();
return rc == tlen + 4 + plength;
return rc == tlen + 3 + llen + plength;
}
boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) {
@@ -525,7 +525,7 @@ uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t po
const char* idp = string;
uint16_t i = 0;
pos += 2;
while (*idp) {
while (*idp && pos < (MQTT_MAX_PACKET_SIZE - 2)) {
buf[pos++] = *idp++;
i++;
}
+1 -1
View File
@@ -73,7 +73,7 @@
#define MQTTQOS1 (1 << 1)
#define MQTTQOS2 (2 << 1)
#ifdef ESP8266
#if defined(ESP8266) || defined(ESP32)
#include <functional>
#define MQTT_CALLBACK_SIGNATURE std::function<void(char*, uint8_t*, unsigned int)> callback
#else
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
PATCH=puya.patch
for DIR in ~/.platformio/packages/framework-arduinoespressif8266*/; do
#not applied yet? (in upstream or otherwise)
if ! grep FLASH_QUIRK_WRITE_0_TO_1 $DIR/cores/esp8266/Esp.cpp >/dev/null; then
echo "Patching $DIR"
patch -p1 -d $DIR < $PATCH
fi
done
+32
View File
@@ -0,0 +1,32 @@
---
cores/esp8266/Esp.cpp | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/cores/esp8266/Esp.cpp b/cores/esp8266/Esp.cpp
index f4c0b220..c5c32f74 100644
--- a/cores/esp8266/Esp.cpp
+++ b/cores/esp8266/Esp.cpp
@@ -501,7 +501,21 @@ bool EspClass::flashEraseSector(uint32_t sector) {
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) {
ets_isr_mask(FLASH_INT_MASK);
- int rc = spi_flash_write(offset, (uint32_t*) data, size);
+ int rc;
+ uint32_t* ptr = data;
+#ifdef FLASH_QUIRK_WRITE_0_TO_1
+ static uint32_t read_buf[SPI_FLASH_SEC_SIZE / 4];
+ rc = spi_flash_read(offset, read_buf, size);
+ if (rc != 0) {
+ ets_isr_unmask(FLASH_INT_MASK);
+ return false;
+ }
+ for (size_t i = 0; i < size / 4; ++i) {
+ read_buf[i] &= data[i];
+ }
+ ptr = read_buf;
+#endif // FLASH_QUIRK_WRITE_0_TO_1
+ rc = spi_flash_write(offset, ptr, size);
ets_isr_unmask(FLASH_INT_MASK);
return rc == 0;
}
--
+67 -9
View File
@@ -7,7 +7,7 @@
#minimal version for esps with 512K or less flash (only has minimal plugin set)
; [env:mini_512]
; platform = espressif8266
; platform = espressif8266@1.5.0
; framework = arduino
; board = esp01
; upload_speed=460800
@@ -22,11 +22,23 @@
[common]
build_flags = -D BUILD_GIT='"${env.TRAVIS_TAG}"'
lib_deps = ""
#normal version with stable plugins, 1024k version
[env:normal_ESP8266_1024]
platform = espressif8266
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld
# upload_port = /dev/ttyUSB0
[env:normal_ESP8266_1024_DOUT]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
board_flash_mode = dout
framework = arduino
board = esp12e
upload_speed=460800
@@ -35,7 +47,8 @@ build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld
#normal version with stable plugins, 4096k version
[env:normal_ESP8266_4096]
platform = espressif8266
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
@@ -44,7 +57,8 @@ build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld
#normal version with stable plugins, 4096k version for esp8285
[env:normal_ESP8285_1024]
platform = espressif8266
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp8285
upload_speed=460800
@@ -54,7 +68,8 @@ build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -DESP8285
#version with additional plugins (and dependend code) that are in test-stadium 1024k
[env:test_ESP8266_1024]
platform = espressif8266
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
@@ -62,15 +77,25 @@ build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -D PLUGIN_BUILD
#version with additional plugins (and dependend code) that are in test-stadium 4096k
[env:test_ESP8266_4096]
platform = espressif8266
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld -D PLUGIN_BUILD_TESTING
[env:test_ESP8266_4096_VCC]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld -D PLUGIN_BUILD_TESTING -D FEATURE_ADC_VCC=true
#version with additional plugins (and dependend code) that are in test-stadium 4096k for esp8285
[env:test_ESP8285_1024]
platform = espressif8266
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp8285
upload_speed=460800
@@ -79,7 +104,8 @@ build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -D PLUGIN_BUILD
#version with additional plugins (and dependend code) that is in development (probably broken or incomplete) 1024k
[env:dev_ESP8266_1024]
platform = espressif8266
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
@@ -87,16 +113,48 @@ build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -D PLUGIN_BUILD
#version with additional plugins (and dependend code) that is in development (probably broken or incomplete) 4096k
[env:dev_ESP8266_4096]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld -D PLUGIN_BUILD_TESTING -D PLUGIN_BUILD_DEV
#version with additional plugins (and dependend code) that is in development (probably broken or incomplete) 4096k
# Use latest ESP8266 core 2.4.0
[env:dev_ESP8266_4096_core2_4_0]
platform = espressif8266
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld -D PLUGIN_BUILD_TESTING -D PLUGIN_BUILD_DEV
#version with additional plugins (and dependend code) that is in development (probably broken or incomplete) 4096k for esp8285
[env:dev_ESP8285_1024]
platform = espressif8266
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp8285
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -D PLUGIN_BUILD_TESTING -D PLUGIN_BUILD_DEV -DESP8285
#special patched version for PUYA flash chips, see https://github.com/letscontrolit/ESPEasy/issues/650
[env:dev_ESP8266PUYA_1024]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -D PLUGIN_BUILD_TESTING -D PLUGIN_BUILD_DEV -D FLASH_QUIRK_WRITE_0_TO_1
#special patched version for PUYA flash chips, see https://github.com/letscontrolit/ESPEasy/issues/650
[env:dev_ESP8266PUYA_1024_VCC]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -D PLUGIN_BUILD_TESTING -D PLUGIN_BUILD_DEV -D FLASH_QUIRK_WRITE_0_TO_1 -D FEATURE_ADC_VCC=true
+11 -2
View File
@@ -4,7 +4,16 @@ NEW="$1"
[ "$NEW" != "" ] || exit 1
PREV=`git tag --sort=creatordate|tail -1`
echo "Creating release $NEW"
if git describe "$NEW" &>/dev/null; then
echo "Release already exists"
exit 1
fi
NEWBASE=`echo "$NEW"|cut -f1 -d'-'`
PREV=`git tag --sort=creatordate|grep "^$NEWBASE"|tail -1`
############## update Release_notes.txt
NOTES="dist/Release_notes.txt"
@@ -34,5 +43,5 @@ git tag -a "$NEW" -m "`cat /tmp/tagmessage`"
################ push everything
git push
git push origin HEAD
git push --tags
Executable
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
# Call this from a cronjob every day to trigger a nightly build via travis.
git pull
#new commits since last tag?
BRANCH=`git rev-parse --abbrev-ref HEAD`
if ! git describe --exact-match 2>/dev/null | grep "^$BRANCH"; then
TAG="$BRANCH-`date +%Y%m%d`"
./release "$TAG"
fi
+104 -18
View File
@@ -42,6 +42,7 @@ bool safeReadStringUntil(Stream &input, String &str, char terminator, unsigned i
#define INPUT_COMMAND_SIZE 80
void ExecuteCommand(byte source, const char *Line)
{
checkRAM(F("ExecuteCommand"));
String status = "";
boolean success = false;
char TmpStr1[80];
@@ -127,7 +128,7 @@ void ExecuteCommand(byte source, const char *Line)
SendUDPCommand(Par1, (char*)event.c_str(), event.length());
}
}
#ifdef FEATURE_SD
if (strcasecmp_P(Command, PSTR("sdcard")) == 0)
{
success = true;
@@ -146,6 +147,7 @@ void ExecuteCommand(byte source, const char *Line)
Serial.println(fname.c_str());
SD.remove((char*)fname.c_str());
}
#endif
if (strcasecmp_P(Command, PSTR("lowmem")) == 0)
{
@@ -178,6 +180,21 @@ void ExecuteCommand(byte source, const char *Line)
delay(60000);
}
if (strcasecmp_P(Command, PSTR("accessinfo")) == 0)
{
success = true;
Serial.print(F("Allowed IP range : "));
Serial.println(describeAllowedIPrange());
}
if (strcasecmp_P(Command, PSTR("clearaccessblock")) == 0)
{
success = true;
clearAccessBlock();
Serial.print(F("Allowed IP range : "));
Serial.println(describeAllowedIPrange());
}
if (strcasecmp_P(Command, PSTR("meminfo")) == 0)
{
success = true;
@@ -197,6 +214,14 @@ void ExecuteCommand(byte source, const char *Line)
taskClear(Par1 - 1, true);
}
//quickly clear all tasks, without saving (used by test suite)
if (strcasecmp_P(Command, PSTR("TaskClearAll")) == 0)
{
success = true;
for (byte t=0; t<TASKS_MAX; t++)
taskClear(t, false);
}
if (strcasecmp_P(Command, PSTR("wdconfig")) == 0)
{
success = true;
@@ -350,15 +375,19 @@ void ExecuteCommand(byte source, const char *Line)
}
if (strcasecmp_P(Command, PSTR("Publish")) == 0 && WiFi.status() == WL_CONNECTED)
{
success = true;
String event = Line;
event = event.substring(8);
int index = event.indexOf(',');
if (index > 0)
{
String topic = event.substring(0, index);
String value = event.substring(index + 1);
MQTTclient.publish(topic.c_str(), value.c_str(), Settings.MQTTRetainFlag);
// ToDo TD-er: Not sure about this function, but at least it sends to an existing MQTTclient
int enabledMqttController = firstEnabledMQTTController();
if (enabledMqttController >= 0) {
success = true;
String event = Line;
event = event.substring(8);
int index = event.indexOf(',');
if (index > 0)
{
String topic = event.substring(0, index);
String value = event.substring(index + 1);
MQTTpublish(enabledMqttController, topic.c_str(), value.c_str(), Settings.MQTTRetainFlag);
}
}
}
@@ -370,12 +399,17 @@ void ExecuteCommand(byte source, const char *Line)
String port = parseString(strLine, 3);
int msgpos = getParamStartPos(strLine, 4);
String message = strLine.substring(msgpos);
byte ipaddress[4];
str2ip((char*)ip.c_str(), ipaddress);
IPAddress UDP_IP(ipaddress[0], ipaddress[1], ipaddress[2], ipaddress[3]);
portUDP.beginPacket(UDP_IP, port.toInt());
portUDP.write(message.c_str(), message.length());
portUDP.endPacket();
IPAddress UDP_IP;
if(UDP_IP.fromString(ip)) {
portUDP.beginPacket(UDP_IP, port.toInt());
#if defined(ESP8266)
portUDP.write(message.c_str(), message.length());
#endif
#if defined(ESP32)
portUDP.write((uint8_t*)message.c_str(), message.length());
#endif
portUDP.endPacket();
}
}
if (strcasecmp_P(Command, PSTR("SendToHTTP")) == 0 && WiFi.status() == WL_CONNECTED)
@@ -412,6 +446,43 @@ void ExecuteCommand(byte source, const char *Line)
}
}
// ****************************************
// special commands for Blynk
// ****************************************
#ifdef CPLUGIN_012
//FIXME: this should go to PLUGIN_WRITE in _C012.ino
if (strcasecmp_P(Command, PSTR("BlynkGet")) == 0)
{
byte first_enabled_blynk_controller = firstEnabledBlynkController();
if (first_enabled_blynk_controller == -1) {
status = F("Controller not enabled");
} else {
String strLine = Line;
strLine = strLine.substring(9);
int index = strLine.indexOf(',');
if (index > 0)
{
int index = strLine.lastIndexOf(',');
String blynkcommand = strLine.substring(index+1);
float value = 0;
if (Blynk_get(blynkcommand, first_enabled_blynk_controller, &value))
{
UserVar[(VARS_PER_TASK * (Par1 - 1)) + Par2 - 1] = value;
}
else
status = F("Error getting data");
}
else
{
if (!Blynk_get(strLine, first_enabled_blynk_controller))
{
status = F("Error getting data");
}
}
}
}
#endif
// ****************************************
// configure settings commands
@@ -489,7 +560,12 @@ void ExecuteCommand(byte source, const char *Line)
pinMode(0, INPUT);
pinMode(2, INPUT);
pinMode(15, INPUT);
ESP.reset();
#if defined(ESP8266)
ESP.reset();
#endif
#if defined(ESP32)
ESP.restart();
#endif
}
if (strcasecmp_P(Command, PSTR("Restart")) == 0)
@@ -509,6 +585,13 @@ void ExecuteCommand(byte source, const char *Line)
{
success = true;
ResetFactory();
#if defined(ESP8266)
ESP.reset();
#endif
#if defined(ESP32)
ESP.restart();
#endif
}
if (strcasecmp_P(Command, PSTR("Save")) == 0)
@@ -532,9 +615,10 @@ void ExecuteCommand(byte source, const char *Line)
if (strcasecmp_P(Command, PSTR("IP")) == 0)
{
success = true;
if (GetArgv(Line, TmpStr1, 2))
if (GetArgv(Line, TmpStr1, 2)) {
if (!str2ip(TmpStr1, Settings.IP))
Serial.println("?");
}
}
if (strcasecmp_P(Command, PSTR("Settings")) == 0)
@@ -567,6 +651,7 @@ void ExecuteCommand(byte source, const char *Line)
yield();
}
#ifdef FEATURE_SD
void printDirectory(File dir, int numTabs) {
while (true) {
@@ -590,3 +675,4 @@ void printDirectory(File dir, int numTabs) {
entry.close();
}
}
#endif
+97 -64
View File
@@ -3,7 +3,8 @@
//********************************************************************************
void sendData(struct EventStruct *event)
{
LoadTaskSettings(event->TaskIndex);
checkRAM(F("sendData"));
LoadTaskSettings(event->TaskIndex);
if (Settings.UseRules)
createRuleEvents(event->TaskIndex);
@@ -24,7 +25,8 @@ void sendData(struct EventStruct *event)
uint16_t delayms = Settings.MessageDelay - dif;
//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);
delayBackground(delayms);
// unsigned long timer = millis() + delayms;
// while (!timeOutReached(timer))
@@ -38,11 +40,19 @@ void sendData(struct EventStruct *event)
{
event->ControllerIndex = x;
event->idx = Settings.TaskDeviceID[x][event->TaskIndex];
if (Settings.TaskDeviceSendData[event->ControllerIndex][event->TaskIndex] && Settings.ControllerEnabled[event->ControllerIndex] && Settings.Protocol[event->ControllerIndex])
if (Settings.TaskDeviceSendData[event->ControllerIndex][event->TaskIndex] &&
Settings.ControllerEnabled[event->ControllerIndex] && Settings.Protocol[event->ControllerIndex])
{
event->ProtocolIndex = getProtocolIndex(Settings.Protocol[event->ControllerIndex]);
CPlugin_ptr[event->ProtocolIndex](CPLUGIN_PROTOCOL_SEND, event, dummyString);
if (validUserVar(event)) {
CPlugin_ptr[event->ProtocolIndex](CPLUGIN_PROTOCOL_SEND, event, dummyString);
} else {
String log = F("Invalid value detected for controller ");
String controllerName;
CPlugin_ptr[event->ProtocolIndex](CPLUGIN_GET_DEVICENAME, event, controllerName);
log += controllerName;
addLog(LOG_LEVEL_DEBUG, log);
}
}
}
@@ -50,6 +60,13 @@ void sendData(struct EventStruct *event)
lastSend = millis();
}
boolean validUserVar(struct EventStruct *event) {
for (int i = 0; i < VARS_PER_TASK; ++i) {
const float f(UserVar[event->BaseVarIndex + i]);
if (!isValidFloat(f)) return false;
}
return true;
}
/*********************************************************************************************\
* Handle incoming MQTT messages
@@ -60,10 +77,15 @@ void callback(char* c_topic, byte* b_payload, unsigned int length) {
char c_payload[384];
statusLED(true);
if (length>sizeof(c_payload)-1)
int enabledMqttController = firstEnabledMQTTController();
if (enabledMqttController < 0) {
addLog(LOG_LEVEL_ERROR, F("MQTT : No enabled MQTT controller"));
return;
}
if ((length + 1) > sizeof(c_payload))
{
addLog(LOG_LEVEL_ERROR, F("MQTT : Ignored too big message"));
return;
}
//convert payload to string, and 0 terminate
@@ -87,7 +109,7 @@ void callback(char* c_topic, byte* b_payload, unsigned int length) {
struct EventStruct TempEvent;
TempEvent.String1 = c_topic;
TempEvent.String2 = c_payload;
byte ProtocolIndex = getProtocolIndex(Settings.Protocol[0]);
byte ProtocolIndex = getProtocolIndex(Settings.Protocol[enabledMqttController]);
CPlugin_ptr[ProtocolIndex](CPLUGIN_PROTOCOL_RECV, &TempEvent, dummyString);
}
@@ -95,12 +117,14 @@ void callback(char* c_topic, byte* b_payload, unsigned int length) {
/*********************************************************************************************\
* Connect to MQTT message broker
\*********************************************************************************************/
void MQTTConnect()
bool MQTTConnect(int controller_idx)
{
if (WiFi.status() != WL_CONNECTED) return;
ControllerSettingsStruct ControllerSettings;
LoadControllerSettings(0, (byte*)&ControllerSettings, sizeof(ControllerSettings)); // todo index is now fixed to 0
LoadControllerSettings(controller_idx, (byte*)&ControllerSettings, sizeof(ControllerSettings));
if (!ControllerSettings.checkHostReachable(true))
return false;
if (MQTTclient.connected())
MQTTclient.disconnect();
if (ControllerSettings.UseDNS) {
MQTTclient.setServer(ControllerSettings.getHost().c_str(), ControllerSettings.Port);
} else {
@@ -109,72 +133,72 @@ void MQTTConnect()
MQTTclient.setCallback(callback);
// MQTT needs a unique clientname to subscribe to broker
String clientid = "ESPClient";
clientid += Settings.Unit;
String subscribeTo = "";
String clientid = F("ESPClient_");
clientid += WiFi.macAddress();
String LWTTopic = ControllerSettings.Subscribe;
LWTTopic.replace(F("/#"), F("/status"));
LWTTopic.replace(F("%sysname%"), Settings.Name);
LWTTopic += F("/LWT"); // Extend the topic for status updates of connected/disconnected status.
for (byte x = 1; x < 3; x++)
{
String log = "";
boolean MQTTresult = false;
boolean MQTTresult = false;
uint8_t willQos = 0;
boolean willRetain = true;
if ((SecuritySettings.ControllerUser[0] != 0) && (SecuritySettings.ControllerPassword[0] != 0))
MQTTresult = MQTTclient.connect(clientid.c_str(), SecuritySettings.ControllerUser[0], SecuritySettings.ControllerPassword[0], LWTTopic.c_str(), 0, 0, "Connection Lost");
else
MQTTresult = MQTTclient.connect(clientid.c_str(), LWTTopic.c_str(), 0, 0, "Connection Lost");
if (MQTTresult)
{
log = F("MQTT : Connected to broker");
addLog(LOG_LEVEL_INFO, log);
subscribeTo = ControllerSettings.Subscribe;
subscribeTo.replace(F("%sysname%"), Settings.Name);
MQTTclient.subscribe(subscribeTo.c_str());
log = F("Subscribed to: ");
log += subscribeTo;
addLog(LOG_LEVEL_INFO, log);
MQTTclient.publish(LWTTopic.c_str(), "Connected");
statusLED(true);
break; // end loop if succesfull
}
else
{
log = F("MQTT : Failed to connect to broker");
addLog(LOG_LEVEL_ERROR, log);
}
delay(500);
if ((SecuritySettings.ControllerUser[controller_idx] != 0) && (SecuritySettings.ControllerPassword[controller_idx] != 0)) {
MQTTresult = MQTTclient.connect(clientid.c_str(), SecuritySettings.ControllerUser[controller_idx], SecuritySettings.ControllerPassword[controller_idx],
LWTTopic.c_str(), willQos, willRetain, "Connection Lost");
} else {
MQTTresult = MQTTclient.connect(clientid.c_str(), LWTTopic.c_str(), willQos, willRetain, "Connection Lost");
}
yield();
if (!MQTTresult) {
addLog(LOG_LEVEL_ERROR, F("MQTT : Failed to connect to broker"));
return false;
}
MQTTclient_should_reconnect = false;
String log = F("MQTT : Connected to broker with client ID: ");
log += clientid;
addLog(LOG_LEVEL_INFO, log);
String subscribeTo = ControllerSettings.Subscribe;
parseSystemVariables(subscribeTo, false);
MQTTclient.subscribe(subscribeTo.c_str());
log = F("Subscribed to: ");
log += subscribeTo;
addLog(LOG_LEVEL_INFO, log);
if (MQTTclient.publish(LWTTopic.c_str(), "Connected", 1)) {
statusLED(true);
return true; // end loop if succesfull
}
return false;
}
/*********************************************************************************************\
* Check connection MQTT message broker
\*********************************************************************************************/
void MQTTCheck()
bool MQTTCheck(int controller_idx)
{
byte ProtocolIndex = getProtocolIndex(Settings.Protocol[0]);
byte ProtocolIndex = getProtocolIndex(Settings.Protocol[controller_idx]);
if (Protocol[ProtocolIndex].usesMQTT)
{
if (!MQTTclient.connected() || WiFi.status() != WL_CONNECTED)
if (MQTTclient_should_reconnect || !WiFiConnected(10) || !MQTTclient.connected())
{
addLog(LOG_LEVEL_ERROR, F("MQTT : Connection lost"));
connectionFailures += 2;
MQTTclient.disconnect();
if (WiFi.status() == WL_CONNECTED) {
delay(1000);
MQTTConnect();
if (MQTTclient_should_reconnect) {
addLog(LOG_LEVEL_ERROR, F("MQTT : Intentional reconnect"));
} else {
addLog(LOG_LEVEL_ERROR, F("MQTT : Connection lost"));
connectionFailures += 2;
}
}
else if (connectionFailures)
return MQTTConnect(controller_idx);
} else if (connectionFailures) {
connectionFailures--;
}
}
// When no MQTT protocol is enabled, all is fine.
return true;
}
@@ -199,6 +223,13 @@ void SendStatus(byte source, String status)
}
}
boolean MQTTpublish(int controller_idx, const char* topic, const char* payload, boolean retained)
{
if (MQTTclient.publish(topic, payload, retained))
return true;
addLog(LOG_LEVEL_DEBUG, F("MQTT : publish failed"));
return false;
}
/*********************************************************************************************\
* Send status info back to channel where request came from
@@ -206,10 +237,12 @@ void SendStatus(byte source, String status)
void MQTTStatus(String& status)
{
ControllerSettingsStruct ControllerSettings;
LoadControllerSettings(0, (byte*)&ControllerSettings, sizeof(ControllerSettings)); // todo index is now fixed to 0
String pubname = ControllerSettings.Subscribe;
pubname.replace(F("/#"), F("/status"));
pubname.replace(F("%sysname%"), Settings.Name);
MQTTclient.publish(pubname.c_str(), status.c_str(),Settings.MQTTRetainFlag);
int enabledMqttController = firstEnabledMQTTController();
if (enabledMqttController >= 0) {
LoadControllerSettings(enabledMqttController, (byte*)&ControllerSettings, sizeof(ControllerSettings));
String pubname = ControllerSettings.Subscribe;
pubname.replace(F("/#"), F("/status"));
pubname.replace(F("%sysname%"), Settings.Name);
MQTTpublish(enabledMqttController, pubname.c_str(), status.c_str(),Settings.MQTTRetainFlag);
}
}

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